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
- Verify the apiUrl and any API key passed to setupGhostApi are correct and point to the live Ghost Content API endpoint.
- 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).
- Ensure the Ghost instance is running and the announcement-bar integration is installed and active.
- 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
- Verify the apiUrl passed to setupGhostApi is the correct Content API endpoint before initializing.
- Wrap api.init() in a try/catch at the app bootstrap so a failure does not crash the host page.
- Check the Network tab for the failing request's status to distinguish config errors (401/404) from server errors (5xx).
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
- Failed to fetch changelog: ${response.status}
- Failed to update member
- Failed to fetch site data
- Failed to fetch comments
- Failed to fetch replies
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/db52efc53baa5e02.
Report an issue: GitHub.