TryGhost/Ghost · error · Error

Failed to fetch site data

Error message

Failed to fetch site data

What it means

The announcement-bar app's setupGhostApi creates an announcementSettings.browse() method that GETs the configured apiUrl. If the response is not ok (HTTP non-2xx), it throws this generic message. The error propagates to api.init() which awaits browse() and is the app's bootstrap — a failure here prevents the announcement bar from loading.

Source

Thrown at apps/announcement-bar/src/utils/api.js:26

        };
        return fetch(url, options);
    }
    const api = {};

    api.announcementSettings = {
        browse() {
            const url = apiUrl;
            return makeRequest({
                url,
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json'
                }
            }).then(function (res) {
                if (res.ok) {
                    return res.json();
                } else {
                    throw new Error('Failed to fetch site data');
                }
            });
        }
    };

    api.init = async () => {
        let {announcement} = await api.announcementSettings.browse();
        return announcement[0];
    };

    return api;
}

export default setupGhostApi;

View on GitHub (pinned to 47d8b0e2ad)

Solutions

  1. Verify the apiUrl and any API key passed to setupGhostApi are correct and point to the live Ghost Content API endpoint.
  2. Check the Network tab for the failing request's status code and response body to distinguish 401 (bad key) from 404 (wrong URL) from 5xx (server).
  3. Ensure the Ghost instance is running and the announcement-bar integration is installed and active.
  4. Confirm CORS headers are present if the bar loads on a different origin than the API.
Defensive patterns

Strategy: try-catch

Validate before calling

function isAnnouncementApiConfigured(apiUrl: string | undefined): boolean {
  return typeof apiUrl === 'string' && apiUrl.length > 0 && /^https?:\/\//.test(apiUrl);
}

Try / catch

try {
  const announcement = await api.init();
} catch (e) {
  if (e instanceof Error && e.message === 'Failed to fetch site data') {
    // render the bar in a disabled/hidden state; log the apiUrl
  }
  throw e;
}

Prevention

When it happens

Trigger: The GET to the announcement-bar apiUrl returns 4xx or 5xx. The apiUrl is misconfigured (points to a wrong endpoint, missing a content key, hits a non-existent route), the Ghost site is down, CORS blocks the cross-origin request (though CORS typically rejects before res.ok is evaluated), or the content API key is invalid yielding 401/403.

Common situations: The announcement-bar script is embedded on a page where the apiUrl variable was not set or points to a staging endpoint that is offline. The Content API key embedded in the script is expired or belongs to a different site. The Ghost version does not have the announcement-bar integration enabled.

Related errors


AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13). Data as JSON: /api/errors/db52efc53baa5e02. Report an issue: GitHub.