Fix: Paraglide Not Working — Messages Not Loading, Compiler Errors, or Framework Integration Issues
Quick Answer
How to fix Paraglide.js i18n issues — message compilation, type-safe translations, SvelteKit and Next.js integration, language switching, and message extraction from existing code.
The Problem
Paraglide messages are undefined:
import * as m from '$lib/paraglide/messages';
m.welcome();
// TypeError: m.welcome is not a functionOr the compiler fails:
npx @inlang/paraglide-js compile
# Error: No messages found in projectOr language switching doesn’t update the page:
Language changes in the dropdown but text stays in EnglishWhy This Happens
Paraglide.js is a compile-time i18n library that generates type-safe message functions from translation files. Key differences from runtime i18n:
- Messages are compiled to JavaScript functions — each translation becomes a function like
welcome()that returns the translated string for the current locale. If compilation hasn’t run, the functions don’t exist. - An inlang project file is required — Paraglide reads messages from a
project.inlang/directory containingsettings.jsonand message files. Without proper project setup, the compiler finds nothing. - Language state must be managed per framework — Paraglide doesn’t manage routing or language detection. Framework adapters (SvelteKit, Next.js) handle URL-based language routing and provide the current locale to Paraglide.
- Tree-shaking removes unused translations — only messages actually imported and called end up in the bundle. This is a feature, but it means unused messages aren’t just “available at runtime.”
Fix 1: Basic Setup
npx @inlang/paraglide-js init
# Creates project.inlang/ directory// project.inlang/settings.json
{
"$schema": "https://inlang.com/schema/project-settings",
"sourceLanguageTag": "en",
"languageTags": ["en", "ja", "es", "fr"],
"modules": [
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@latest/dist/index.js"
],
"plugin.inlang.messageFormat": {
"pathPattern": "./messages/{languageTag}.json"
}
}// messages/en.json
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"welcome": "Welcome to our app",
"greeting": "Hello, {name}!",
"items_count": "{count, plural, =0 {No items} one {# item} other {# items}}",
"nav_home": "Home",
"nav_about": "About",
"nav_contact": "Contact"
}
// messages/ja.json
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"welcome": "アプリへようこそ",
"greeting": "こんにちは、{name}さん!",
"items_count": "{count, plural, other {{count}個のアイテム}}",
"nav_home": "ホーム",
"nav_about": "概要",
"nav_contact": "お問い合わせ"
}# Compile messages to JavaScript functions
npx @inlang/paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide// Generated: src/lib/paraglide/messages.ts
// Each message becomes a type-safe function:
// export function welcome(): string
// export function greeting(params: { name: string }): string
// export function items_count(params: { count: number }): stringFix 2: SvelteKit Integration
npm install @inlang/paraglide-sveltekit// vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import { paraglide } from '@inlang/paraglide-sveltekit/vite';
export default defineConfig({
plugins: [
paraglide({
project: './project.inlang',
outdir: './src/lib/paraglide',
}),
sveltekit(),
],
});// src/lib/i18n.ts
import { createI18n } from '@inlang/paraglide-sveltekit';
import * as runtime from '$lib/paraglide/runtime';
export const i18n = createI18n(runtime, {
pathnames: {
'/about': {
en: '/about',
ja: '/about',
es: '/acerca-de',
},
},
exclude: ['/api'],
});// src/hooks.ts
import { i18n } from '$lib/i18n';
import type { Handle } from '@sveltejs/kit';
export const handle: Handle = i18n.handle();// src/routes/+layout.ts
import { i18n } from '$lib/i18n';
import type { LayoutLoad } from './$types';
export const load: LayoutLoad = ({ url }) => {
return i18n.layoutLoad({ url });
};<!-- src/routes/+page.svelte -->
<script>
import * as m from '$lib/paraglide/messages';
import { i18n } from '$lib/i18n';
import { languageTag } from '$lib/paraglide/runtime';
</script>
<h1>{m.welcome()}</h1>
<p>{m.greeting({ name: 'Alice' })}</p>
<p>{m.items_count({ count: 5 })}</p>
<!-- Language switcher -->
<nav>
<a href={i18n.route($page.url.pathname)} hreflang="en">English</a>
<a href={i18n.route($page.url.pathname)} hreflang="ja">日本語</a>
<a href={i18n.route($page.url.pathname)} hreflang="es">Español</a>
</nav>
<p>Current: {languageTag()}</p>Fix 3: Next.js Integration
npm install @inlang/paraglide-next// next.config.mjs
import { paraglide } from '@inlang/paraglide-next/plugin';
export default paraglide({
paraglide: {
project: './project.inlang',
outdir: './src/lib/paraglide',
},
// Next.js config
});// src/lib/i18n.ts
import { createI18n } from '@inlang/paraglide-next';
import * as runtime from '@/lib/paraglide/runtime';
export const { middleware, Link, useRouter, usePathname, redirect, permanentRedirect } =
createI18n(runtime);// middleware.ts
export { middleware } from '@/lib/i18n';
export const config = {
matcher: ['/((?!api|_next|.*\\..*).*)'],
};// app/[lang]/layout.tsx
import { LanguageProvider } from '@inlang/paraglide-next';
import { languageTag } from '@/lib/paraglide/runtime';
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<LanguageProvider>
<html lang={languageTag()}>
<body>{children}</body>
</html>
</LanguageProvider>
);
}// app/[lang]/page.tsx — use translations
import * as m from '@/lib/paraglide/messages';
import { Link } from '@/lib/i18n';
export default function Home() {
return (
<div>
<h1>{m.welcome()}</h1>
<p>{m.greeting({ name: 'Alice' })}</p>
{/* Type-safe Link with locale handling */}
<Link href="/about">
{m.nav_about()}
</Link>
</div>
);
}Fix 4: Type-Safe Message Parameters
// messages/en.json
{
"order_status": "Order #{orderId} is {status}",
"price": "Total: {amount, number, ::currency/USD}",
"last_login": "Last login: {date, date, medium}",
"file_size": "{size, number, ::compact-short} bytes",
"progress": "{percent, number, ::percent} complete"
}// Generated functions are fully typed:
import * as m from '$lib/paraglide/messages';
m.order_status({ orderId: '12345', status: 'shipped' });
// "Order #12345 is shipped"
m.greeting({ name: 'Alice' });
// TypeScript error if name is missing:
// m.greeting({}) // Error: Property 'name' is missing
// Unused messages are tree-shaken from the bundle
// Only imported messages end up in production codeFix 5: Development Workflow
# Compile messages (run after editing .json files)
npx @inlang/paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide
# Watch mode — recompile on message changes
npx @inlang/paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide --watch
# With the Vite plugin, compilation is automatic during dev// package.json
{
"scripts": {
"i18n:compile": "paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide",
"dev": "npm run i18n:compile && vite dev",
"build": "npm run i18n:compile && vite build",
"i18n:lint": "npx @inlang/cli lint --project ./project.inlang"
}
}# Lint translations — find missing or empty messages
npx @inlang/cli lint --project ./project.inlang
# Output:
# ⚠ Missing translation for "nav_contact" in "ja"
# ⚠ Empty pattern for "description" in "es"Fix 6: Using the Inlang Editor
# Visual editor for translations (VS Code extension or web app)
# Install: Sherlock — i18n inspector (VS Code extension)
# Or use the Fink web editor:
# Open: https://fink.inlang.com
# Load your project.inlang/ directory
# Translators can edit messages in a web UIStill Not Working?
m.welcome is not a function — the paraglide output hasn’t been compiled. Run npx @inlang/paraglide-js compile or ensure the Vite/Next.js plugin is configured. The outdir must match your import path ($lib/paraglide for SvelteKit, @/lib/paraglide for Next.js).
Compiler finds no messages — project.inlang/settings.json must point to the correct message files. Check plugin.inlang.messageFormat.pathPattern matches where your .json files are. The default is ./messages/{languageTag}.json.
Language switching doesn’t update text — Paraglide needs the framework adapter to manage the current locale. In SvelteKit, use i18n.handle() in hooks. In Next.js, use the Paraglide middleware. Without the adapter, languageTag() always returns the default.
Bundle still includes all languages — Paraglide tree-shakes unused messages but includes all languages for used messages. This is by design — the current locale is determined at runtime. The per-language overhead is minimal (just the translated strings, no library code).
For related i18n issues, see Fix: i18next Not Working and Fix: Lingui Not Working.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Svelte 5 Runes Not Working — $state Not Reactive, $derived Not Updating, or $effect Running Twice
How to fix Svelte 5 Runes issues — $state and $state.raw reactivity, $derived computations, $effect lifecycle, $props and $bindable, migration from Svelte 4 stores, and component patterns.
Fix: Svelte Store Not Updating — Reactive Store Issues
How to fix Svelte store not updating the UI — writable vs readable stores, derived stores, subscribe pattern, store mutation vs assignment, and custom store patterns.
Fix: CodeMirror Not Working — Editor Not Rendering, Extensions Not Loading, or React State Out of Sync
How to fix CodeMirror 6 issues — basic setup, language and theme extensions, React integration, vim mode, collaborative editing, custom keybindings, and read-only mode.
Fix: GSAP Not Working — Animations Not Playing, ScrollTrigger Not Firing, or React Cleanup Issues
How to fix GSAP animation issues — timeline and tween basics, ScrollTrigger setup, React useGSAP hook, cleanup and context, SplitText, stagger animations, and Next.js integration.