DEV Community

Cover image for How to Pass Data into a Static JavaScript File Using data-* Attributes
Zahra Mirkazemi
Zahra Mirkazemi

Posted on

How to Pass Data into a Static JavaScript File Using data-* Attributes

As a front-end developer, one of the common challenges you'll encounter when working with embeddable scripts or static widgets is how to inject dynamic configuration into a static JavaScript file.

Since static files can't fetch data from a backend or receive props like React components, they must rely on what's available in the DOM.

One elegant and widely supported solution is to use HTML data-* attributes.

In this article, I'll walk through how this pattern works, when to use it, and why it's a reliable choice for flexible, embeddable scripts.

๐ŸŽฏ The Problem

Let's say you're distributing a static script โ€” for example, a survey button, a help widget, or a third-party plugin. You want other developers (or non-dev users) to embed your script and be able to customize things like:

  • Color scheme
  • Position (left/right/bottom)
  • Icon

But your JavaScript file is hosted on a CDN and cannot be dynamically modified.

So, how do you make it configurable?

โœ… The data-* Attribute Pattern

HTML data-* attributes let you attach custom metadata to elements. These values are accessible via JavaScript using the .dataset API.

Here's how it works:

<div
  id="my-widget"
  data-theme="dark"
  data-position="right"
  data-lang="en"
></div>
<script src="https://cdn.example.com/widget.js"></script>
Enter fullscreen mode Exit fullscreen mode

Inside widget.js:

const el = document.getElementById("my-widget");
const config = {
  theme: el.dataset.theme || "light",
  position: el.dataset.position || "left",
  lang: el.dataset.lang || "en"
};

// Use the config to customize your widget
initializeWidget(config);
Enter fullscreen mode Exit fullscreen mode

This pattern is clean, readable, and doesn't require any global variables or external communication.

๐Ÿงฐ Why Use This Pattern?

โœ… Pros

  • Fully decoupled: Your static JS doesn't rely on server-side rendering or build-time variables.
  • Declarative: Easy for developers and non-developers to understand.
  • Multiple instances: You can use this pattern for multiple widgets on the same page, each with its own configuration.
  • Safe & flexible: Works across browsers, respects caching, and doesn't interfere with global scope.

โŒ Cons

  • Data is limited to string values โ€” you'll need to manually parse JSON or booleans if needed.
  • Relies on correct HTML structure (e.g., an element with the right id or class).
  • If not documented properly, consumers may miss available options.

โœ๏ธ Best Practices

  • Use clear naming: Stick to data- attributes like data-color, data-user-id, etc.
  • Set safe defaults: In your JS, always provide fallback values.
  • Validate input values (e.g., allowed themes or positions).
  • Avoid sensitive data: Don't pass secrets, tokens, or anything private via data-*.

๐Ÿค” But Waitโ€ฆ This Isn't the Only Way

While data-* attributes are great, they're definitely not the only option. Depending on your use case, you might consider one of these too:

1. Global Variables

<script>
  window.myWidgetConfig = {
    theme: 'dark',
    position: 'right',
    lang: 'fa'
  }
</script>
<script src="https://cdn.example.com/widget.js"></script>
Enter fullscreen mode Exit fullscreen mode

This works well for more structured data, but it pollutes the global namespace โ€” which can be risky in large apps or when multiple scripts are involved.

2. Query Parameters in Script URL

<script src="https://cdn.example.com/widget.js?theme=dark&lang=fa"></script>
Enter fullscreen mode Exit fullscreen mode

You can then parse these inside the script using document.currentScript.src. This is quick and easy for small config values, but can get messy fast if your configuration grows.

3. JSON Inside <script type="application/json">

Another trick is embedding configuration data as JSON in a special script tag:

<script type="application/json" id="my-widget-config">
  {
    "theme": "dark",
    "lang": "fa"
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Then in your JS:

const raw = document.getElementById("my-widget-config").textContent;
const config = JSON.parse(raw);
Enter fullscreen mode Exit fullscreen mode

A bit more setup, but great for complex configs.

๐Ÿ Conclusion

If you're building embeddable JavaScript for third-party use, data-* attributes offer a simple, scalable, and standards-compliant way to receive configuration from the host HTML.

This pattern strikes the right balance between flexibility and safety โ€” especially in environments where your script is embedded across many contexts and domains.

Next time you're working on a static JS file that needs to behave dynamically, consider this technique. It's declarative, reliable, and works in every browser that matters.

๐Ÿ’ฌ Got thoughts, questions, or your own favorite tricks?

Let's continue the conversation in the comments.

  • Have you implemented something like this before? Which method did you go with, and why?
  • Have you tried more advanced techniques like Web Components or JSON-LD-based configurations?

I'd love to hear your take. Let's share ideas โ€” there's always something new to learn ๐ŸŒฑ

๐Ÿ™Œ If you found this useful, feel free to share it with your team or give it a clap!

Top comments (0)