i18next Translations Not Loading? Fix 404s, CORS Issues & Misconfigurations Fast
If your app is showing raw translation keys instead of real text, this guide will walk you through the most common reasons — and how to fix them quickly.
Modern JavaScript applications rely heavily on internationalization (i18n) to reach a global audience. i18next, combined with the i18next-http-backend, makes it easy to load translation files over HTTP.
Yet, one of the most common developer frustrations is watching their translation keys (like welcome_message) appear instead of the translated text. In this article, you’ll learn:
- Why translation files sometimes fail to load
- How to diagnose file-loading errors quickly
- What you need to configure — step by step
- An alternative backend that sidesteps these issues entirely
Let’s dive in.
Why translation files aren’t loading
No matter how carefully you write your translation JSON, if the browser can’t fetch it, i18next.t() will return the raw key. Here are the top culprits.
loadPath misconfiguration
By default, i18next-http-backend tries to fetch /locales/{{lng}}/{{ns}}.json. If your files live under /public/i18n or on a CDN, that path probably won’t exist — resulting in 404s.
Server setup doesn’t serve JSON
Whether you’re on Next.js, Express, or static hosting, you must explicitly serve translation files from the correct directory.
CORS & cross-origin requests
If translation files are hosted on another domain (a CDN or API), missing CORS headers will block the request.
Wrong language or namespace
Requesting a missing namespace or an unsupported language code will also 404.
Diagnosing translation file errors
Before guessing at solutions, inspect the network and enable debug logs:
i18next.init({
debug: true, // set the debug option to true
// ...
backend: { loadPath: '/i18n/{{lng}}/{{ns}}.json' },
fallbackLng: 'en'
})Browser DevTools → Network tab → filter “.json”: look for failed requests (status 404, 403, or CORS errors).
Console logs: you’ll see messages like i18next::backendConnector: loading namespace translation for language en failed.
Step-by-step: Fixing your configuration
1. Put your files in the correct public folder
For example:
- Next.js: place
/public/i18n/en/common.jsonand/public/i18n/de/common.json. Next.js auto-serves/public. - Express:
app.use('/i18n', express.static(path.join(__dirname, 'public/i18n'))) - Static hosts (Netlify, Vercel, S3): ensure your build output includes the
i18ndirectory with JSON files.
2. Configure loadPath to match
// i18n.js
import i18next from 'i18next'
import Backend from 'i18next-http-backend'
import LanguageDetector from 'i18next-browser-languagedetector'
i18next
.use(Backend)
.use(LanguageDetector)
.init({
debug: true,
fallbackLng: 'en',
ns: ['common', 'errors'],
defaultNS: 'common',
backend: {
// adapt the loadPath to match the URL your translations are served/hosted
loadPath: '/i18n/{{lng}}/{{ns}}.json'
}
})3. Handle CORS (if needed)
If you host JSON on cdn.example.com:
backend: {
loadPath: 'https://cdn.example.com/i18n/{{lng}}/{{ns}}.json'
}
// On the CDN/server: add response header
// Access-Control-Allow-Origin: *4. Verify your namespaces & languages
- JSON files must match both
{{lng}}and{{ns}}. - If you use multiple namespaces:
i18next.init({ ns: ['common', 'validation'], defaultNS: 'common' }) - Depending on your integration (e.g. react-i18next), check calls like
useTranslation('my-ns').
Alternative: i18next-locize-backend
If configuring static files or dealing with CORS feels brittle, consider using i18next-locize-backend. It integrates with Locize (our translation management system), and can help with file loading, versioning, and CDN delivery — so you worry less about 404s or stale JSON.
// i18n.js with locize backend
import i18next from 'i18next'
import LocizeBackend from 'i18next-locize-backend'
import LanguageDetector from 'i18next-browser-languagedetector'
i18next
.use(LocizeBackend)
.use(LanguageDetector)
.init({
debug: true,
ns: ['common', 'errors'],
defaultNS: 'common',
backend: {
projectId: 'YOUR_LOCIZE_PROJECT_ID'
}
})Benefits:
- Versioning & CDN: Locize hosts your JSON and delivers it via a fast CDN.
- No server config required: add keys in Locize; your app can fetch them.
- Context & collaboration: manage revisions, review, and keep the app in sync.
Check out this demo video:
Or sign up and try the free trial.
Conclusion
By carefully configuring your loadPath, ensuring your server serves JSON correctly, and handling CORS, you can eliminate the “raw key” problem with i18next-http-backend.
And if you prefer a managed approach, try i18next-locize-backend — it sidesteps many of these issues and adds collaboration features.