[RETURN_TO_DATABASE]
[KNOWLEDGE_NODE_v1.0]

Bilingual Made Easy: Building with Paraglide-js_

6 MIN_READ
ID: BLOG-BILI
[LIVE_ARCHIVE]

Introduction

Providing multi-language support (Internationalization or i18n) is a crucial step to expanding your website's reach and providing a premium user experience to localized audiences. However, setting up i18n in modern fullstack frameworks has traditionally been a painful process.

Many popular i18n libraries rely on runtime dictionary loading. This often leads to performance issues, such as page rendering flashes (where text shifts from English to the target language on load) and bloated Javascript bundles containing large JSON dictionaries.

Paraglide-JS (developed by the Inlang team) changes the paradigm completely by handling internationalization at compile-time. Paraglide generates lean, type-safe translation helper functions that ensure zero runtime overhead and perfect SvelteKit server-side rendering support.


1. Compile-Time i18n Architecture

Unlike traditional libraries that load massive JSON key-value bundles over the network, Paraglide compiles your translation messages directly into small, tree-shakeable JavaScript functions.

If a Svelte component needs a translation string, instead of invoking a generic lookup method like `$t('home.welcome')`, you invoke an explicit generated function:

import * as m from '$lib/paraglide/messages';

// Fully type-safe compile-time translation call
console.log(m.welcome_message({ name: 'Mikeu' }));

This guarantees:

  1. Perfect Type Safety: If a translation key is missing or has incorrect arguments, Svelte check will throw a compile-time error.
  2. Optimal Code Splitting: Only the translation messages used by the active page are bundled into the client build.
  3. No Layout Shift: Since the translations are compiled directly into the rendering code, the SvelteKit server outputs the correct language HTML immediately.

2. Setting Up Message Files

In a Paraglide setup, translations are structured in localized JSON directories (typically under a `messages/` folder).

Here is an example structure:

// messages/en.json
{
	"$schema": "https://inlang.com/schema/inlang-message-format",
	"home_hero_title": "Crafting Brutalist Digital Systems.",
	"home_hero_sub": "Hi, I am {name}, a software engineer focused on extreme performance."
}
// messages/id.json
{
	"$schema": "https://inlang.com/schema/inlang-message-format",
	"home_hero_title": "Membangun Sistem Digital Brutalist.",
	"home_hero_sub": "Halo, saya {name}, seorang software engineer dengan fokus performa ekstrem."
}

During the build process, Paraglide reads these files and compiles them into a highly optimized module at `src/lib/paraglide/`.


3. Utilizing Translations inside Svelte 5 Components

Using Paraglide translations inside Svelte 5 components is extremely simple. Once the translation files are defined, you can import and execute the compiler-generated functions directly:

<script lang="ts">
	import * as m from '$lib/paraglide/messages';
	let userName = $state('Riki');
</script>

<section class="hero-brutalist">
	<h1>{m.home_hero_title()}</h1>
	<p>{m.home_hero_sub({ name: userName })}</p>
</section>

<style>
	.hero-brutalist {
		border: 4px solid var(--foreground);
		padding: 40px;
		background: var(--background);
	}
</style>

4. Implementing a Language Switcher in SvelteKit

To allow users to switch languages on the fly, you must implement a language toggle that safely routes the user to the correct localized pathname. Paraglide provides runtime utilities like `localizeHref` to translate URLs.

Here is a Svelte 5 Navbar language switcher component:

<script lang="ts">
	import { page } from '$app/state';
	import { locales, localizeHref, baseLocale } from '$lib/paraglide/runtime';
	import { goto } from '$app/navigation';

	// Retrieve active locale from Paraglide context
	let activeLocale = $derived(page.url.pathname.startsWith('/id') ? 'id' : 'en');

	function switchLanguage(locale: string) {
		const targetUrl = localizeHref(page.url.pathname, { locale });
		goto(targetUrl);
	}
</script>

<div class="lang-switcher">
	{#each locales as locale}
		<button
			onclick={() => switchLanguage(locale)}
			class="lang-btn {activeLocale === locale ? 'active' : ''}"
		>
			{locale === 'en' ? '🇬🇧 EN' : '🇮🇩 ID'}
		</button>
	{/each}
</div>

<style>
	.lang-switcher {
		display: flex;
		gap: 8px;
		border: 2px solid var(--foreground);
		padding: 4px;
		background: var(--background);
	}
	.lang-btn {
		font-family: monospace;
		font-weight: bold;
		padding: 4px 8px;
		border: none;
		background: transparent;
		cursor: pointer;
		text-transform: uppercase;
	}
	.lang-btn.active {
		background: var(--foreground);
		color: var(--background);
	}
</style>

Conclusion

Paraglide-js establishes a brand new standard for internationalization. By merging compile-time build steps with SvelteKit's native routing, it allows developers to deploy rich, bilingual web applications that stay lightweight and incredibly fast.

0 views
Share
enid