Quick answer
Paste the two-line FXMacroData snippet into your page's HTML where the calendar should appear, then deploy as usual: drag and drop in the Netlify UI or push to Git. It works the same on Vercel, GitHub Pages, and Cloudflare Pages. If your site sends a Content-Security-Policy header, allow https://fxmacrodata.com in script-src and frame-src. The widget is free, needs no API key, and updates itself.
This guide shows how to add a live economic calendar to a static website using the free FXMacroData widget. By the end you will have a deployed page with a calendar of upcoming macro releases, a security policy that allows it, and a clean pattern for React, Next.js, and sites produced by AI site builders.
Who this is for
Owners of static sites on Netlify, Vercel, GitHub Pages, or Cloudflare Pages, including sites generated by AI site builders and React or Next.js single-page apps.
What you will build
A live calendar of confirmed release times on your own page, with no backend, no build plugin, and no data to maintain.
Choose something else when
You use a visual site editor: see the Wix guide or the install guides. To build your own calendar from raw data, use the API.
See the Widget
The economic calendar widget this guide installs shows the same confirmed schedule as the FXMacroData release calendar, sourced from statistics offices and central banks.
Economic calendar widget for USD, EUR, GBP, and JPY. Change currencies, theme, and row count on the widget page.
Prerequisites
- A site you can edit and deploy: an HTML file, a static site generator project, or a React or Next.js app.
- A host: Netlify, Vercel, GitHub Pages, Cloudflare Pages, or any server that serves HTML.
- No FXMacroData account or API key. The widget is free on public pages as long as the attribution link under it stays visible.
A placeholder div with options
Serves the page unchanged
One tag, any number of widgets
Sized to fit its content
Current calendar on every load
Step 1: Configure and Copy the Snippet
Open the economic calendar widget page, choose currencies and theme, and copy the snippet. Setting options there avoids hand-editing attributes later. This is the default form:
<div data-fxmd-widget-type="economic-calendar"
data-fxmd-currencies="USD,EUR,GBP"
data-fxmd-theme="light"
data-fxmd-limit="6"
data-fxmd-height="560"></div>
<script async src="https://fxmacrodata.com/static/js/fxmacrodata-widget.js"></script>
The div marks where the calendar goes and holds its options. The script fills it with the widget, grows the frame to fit the content, and adds one attribution link beneath it, for example "Economic calendar by FXMacroData".
Step 2: Paste It Into the Page HTML
Put the div where the calendar should appear. The widget takes the full width of its container, so place it inside the column or section that should set its width.
<main>
<h1>This week in macro</h1>
<p>Your own commentary goes here.</p>
<section style="max-width:720px">
<div data-fxmd-widget-type="economic-calendar"
data-fxmd-currencies="USD,EUR,GBP"
data-fxmd-theme="auto"
data-fxmd-limit="6"
data-fxmd-height="560"></div>
</section>
</main>
<script async src="https://fxmacrodata.com/static/js/fxmacrodata-widget.js"></script>
One script tag per page is enough for any number of widgets. To add a second widget, such as a countdown to the next Non-Farm Payrolls report, add another div and leave the script tag as it is.
Step 3: Deploy
The widget is plain HTML, so there is nothing to build or install. Deploy the way you already do. The page only changes for visitors once the new version is live on your host.
| Host | How to ship the change | Where a security policy usually lives |
|---|---|---|
| Netlify | Drag and drop the site folder in the Netlify UI, or push to the connected Git repository. | netlify.toml or a _headers file |
| Vercel | Push to the connected Git repository. | Project or framework headers configuration |
| GitHub Pages | Push to the branch your site publishes from. | A meta tag in the page, if you use one |
| Cloudflare Pages | Push to the connected Git repository, or upload the built folder. | A _headers file |
Step 4: Allow the Widget in Your Content-Security-Policy
Skip this step if your site does not send a Content-Security-Policy header. If it does, the browser blocks any script or frame the policy does not list, and the widget area stays empty. Allow https://fxmacrodata.com for scripts and frames. On Netlify with netlify.toml:
[[headers]]
for = "/*"
[headers.values]
Content-Security-Policy = "script-src 'self' https://fxmacrodata.com; frame-src https://fxmacrodata.com"
The same rule in a _headers file:
/*
Content-Security-Policy: script-src 'self' https://fxmacrodata.com; frame-src https://fxmacrodata.com
These examples show only the two directives the widget needs. If you already have a policy, add https://fxmacrodata.com to your existing script-src and frame-src lists and keep the rest of your directives as they are. If your policy also restricts images, add the same origin to img-src so the small logo beside the attribution link loads.
Step 5: React and Next.js
In a component-based app, render the div in a component and load the script once. The loader picks up widget placeholders that are added to the page later, and it exposes window.FXMacroDataWidgets.render() for rendering on demand, which covers client-side route changes.
import { useEffect } from "react";
const LOADER = "https://fxmacrodata.com/static/js/fxmacrodata-widget.js";
export default function EconomicCalendar() {
useEffect(() => {
if (window.FXMacroDataWidgets) {
window.FXMacroDataWidgets.render();
} else if (!document.querySelector(`script[src="${LOADER}"]`)) {
const script = document.createElement("script");
script.src = LOADER;
script.async = true;
document.body.appendChild(script);
}
}, []);
return (
<div data-fxmd-widget-type="economic-calendar"
data-fxmd-currencies="USD,EUR,GBP"
data-fxmd-theme="auto" data-fxmd-height="560" />
);
}
With Next.js, next/script handles loading the script once for you:
import Script from "next/script";
export default function CalendarSection() {
return (
<>
<div data-fxmd-widget-type="economic-calendar"
data-fxmd-currencies="USD,EUR,GBP" data-fxmd-height="560" />
<Script
src="https://fxmacrodata.com/static/js/fxmacrodata-widget.js"
strategy="afterInteractive"
/>
</>
);
}
The React and Next.js install guide keeps the current version of both patterns.
Step 6: Sites Made With AI Site Builders
If an AI site builder writes your pages, the main risk is that it rewrites the snippet: replacing it with its own calendar markup, wrapping the data in a proxy, or dropping the script tag. Tell it to insert the snippet exactly as given. A prompt like this works well:
Add this HTML to the homepage, directly under the hero section.
Insert it verbatim. Do not rewrite it, do not rebuild it as your own
component, and do not fetch or proxy the data yourself.
<div data-fxmd-widget-type="economic-calendar"
data-fxmd-currencies="USD,EUR,GBP"
data-fxmd-theme="auto" data-fxmd-height="560"></div>
<script async src="https://fxmacrodata.com/static/js/fxmacrodata-widget.js"></script>
After the builder finishes, view the page source or the generated file and confirm that both lines are present and unchanged. The AI site builder install guide has more copy-ready prompts.
Options Reference
All options are data-fxmd-* attributes on the div. The economic calendar is one of eight typed widgets; the others, including policy rates, an inflation heatmap, and a release ticker, are in the widget gallery and use the same pattern.
| Attribute | Values | Effect |
|---|---|---|
data-fxmd-currencies | Comma list such as USD,EUR,GBP,JPY | Currencies shown. 22 currencies are supported. |
data-fxmd-theme | dark, light, transparent, auto | auto follows the visitor's light or dark preference. |
data-fxmd-limit | 1 to 12 | Number of rows. |
data-fxmd-importance | all, high, medium | Filters the calendar and countdown by event importance. |
data-fxmd-timezone | viewer | Shows each visitor's local time. The default is UTC. |
data-fxmd-lang | en, fr, es, pt, zh, ja, de, ar | Widget language. |
data-fxmd-height | Pixels | Starting height. The loader then fits the frame to the content. |
data-fxmd-max-width | Pixels | Caps the width. Without it the widget fills its container. |
data-fxmd-publisher-id | Your publisher id | Optional and free. Gives you a stats page; register on any widget page. |
If your platform accepts only a URL or an iframe and no scripts, use the direct widget address instead. In that mode the options go in the query string and the attribution is shown inside the frame:
https://fxmacrodata.com/widgets/embed/economic-calendar?currencies=USD,EUR,GBP&theme=light&limit=6
Troubleshooting
| What you see | Likely cause | Fix |
|---|---|---|
| Empty space, and the browser console reports a Content-Security-Policy violation | The policy does not list the widget's origin. | Add https://fxmacrodata.com to script-src and frame-src, then redeploy. |
| Empty space, no console error | The script tag is missing, or the div attributes were altered. | View the page source and compare both lines with the snippet. |
| Works locally, not on the live site | The change has not been deployed, or the host adds headers your local server does not. | Confirm the deploy finished, then check the response headers on the live URL. |
| The widget disappears after navigating in a single-page app | The component rendered before the loader was ready, or the script was removed on navigation. | Load the script once and call window.FXMacroDataWidgets.render() when the component mounts. |
| The widget is too wide | It fills its container by design. | Place it in a narrower container or set data-fxmd-max-width. |
| An AI-built page shows a static table instead of the widget | The builder replaced the snippet with its own markup. | Ask it to insert the snippet verbatim, then check the generated source. |
Free Use and Attribution
The widget is free on public pages with no account and no API key. The condition is that the attribution link the loader adds under the widget stays visible, so do not hide it with CSS or clip it with a fixed-height container. By default the widget sets no cookies on your site.
If the calendar will sit inside a customer-facing or subscriber-only product, such as a paid dashboard or a client portal, that use needs the Commercial Redistribution add-on.
Sources and Further Reading
- FXMacroData install guide for Netlify and static hosts
- Netlify documentation, for deploys and custom headers.
- MDN: Content-Security-Policy, for the
script-srcandframe-srcdirectives. - React documentation: useEffect and the Next.js documentation.
Related Guides
- How to add a live economic calendar to a Wix site
- How to embed live macro chart widgets on a trading blog
- Install guides for WordPress, Webflow, Ghost, and Shopify
Summary
You pasted the FXMacroData snippet into your page, deployed it, allowed the widget in your Content-Security-Policy where one exists, and saw how to load it once in React and Next.js and how to keep an AI site builder from rewriting it. The calendar now stays current on its own. A natural next step is to add a second widget from the widget gallery on the same script tag, or to register a free publisher id on the widget page to see how your embeds are used.