Skip to content

Commit 3b43211

Browse files
add i18n add-on (paraglide js) (#252)
* add paraglide add commands * fix redirect loop * remove gitignore
1 parent 44e61cd commit 3b43211

File tree

16 files changed

+216
-8
lines changed

16 files changed

+216
-8
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Paraglide i18n
2+
3+
This add-on wires up ParaglideJS for localized routing and message formatting.
4+
5+
- Messages live in `project.inlang/messages`.
6+
- URLs are localized through the Paraglide Vite plugin and router `rewrite` hooks.
7+
- Run the dev server or build to regenerate the `src/paraglide` outputs.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "https://inlang.com/schema/inlang-message-format",
3+
"home_page": "Startseite",
4+
"about_page": "Über uns",
5+
"example_message": "Willkommen in deiner i18n-App.",
6+
"language_label": "Sprache",
7+
"current_locale": "Aktuelle Sprache: {locale}",
8+
"learn_router": "Paraglide JS lernen"
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "https://inlang.com/schema/inlang-message-format",
3+
"home_page": "Home page",
4+
"about_page": "About page",
5+
"example_message": "Welcome to your i18n app.",
6+
"language_label": "Language",
7+
"current_locale": "Current locale: {locale}",
8+
"learn_router": "Learn Paraglide JS"
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"$schema": "https://inlang.com/schema/project-settings",
3+
"baseLocale": "en",
4+
"locales": ["en", "de"],
5+
"modules": [
6+
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js",
7+
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js"
8+
],
9+
"plugin.inlang.messageFormat": {
10+
"pathPattern": "./messages/{locale}.json"
11+
}
12+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Locale switcher refs:
2+
// - Paraglide docs: https://inlang.com/m/gerre34r/library-inlang-paraglideJs
3+
// - Router example: https://github.com/TanStack/router/tree/main/examples/react/i18n-paraglide#switching-locale
4+
import { getLocale, locales, setLocale } from '@/paraglide/runtime'
5+
import { m } from '@/paraglide/messages'
6+
7+
export default function ParaglideLocaleSwitcher() {
8+
const currentLocale = getLocale()
9+
10+
return (
11+
<div
12+
style={{
13+
display: 'flex',
14+
gap: '0.5rem',
15+
alignItems: 'center',
16+
color: 'inherit',
17+
}}
18+
aria-label={m.language_label()}
19+
>
20+
<span style={{ opacity: 0.85 }}>{m.current_locale({ locale: currentLocale })}</span>
21+
<div style={{ display: 'flex', gap: '0.25rem' }}>
22+
{locales.map((locale) => (
23+
<button
24+
key={locale}
25+
onClick={() => setLocale(locale)}
26+
aria-pressed={locale === currentLocale}
27+
style={{
28+
cursor: 'pointer',
29+
padding: '0.35rem 0.75rem',
30+
borderRadius: '999px',
31+
border: '1px solid #d1d5db',
32+
background: locale === currentLocale ? '#0f172a' : 'transparent',
33+
color: locale === currentLocale ? '#f8fafc' : 'inherit',
34+
fontWeight: locale === currentLocale ? 700 : 500,
35+
letterSpacing: '0.01em',
36+
}}
37+
>
38+
{locale.toUpperCase()}
39+
</button>
40+
))}
41+
</div>
42+
</div>
43+
)
44+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { createFileRoute } from "@tanstack/react-router";
2+
import logo from "../logo.svg";
3+
import { m } from "@/paraglide/messages";
4+
import LocaleSwitcher from "../components/LocaleSwitcher";
5+
6+
export const Route = createFileRoute("/demo/i18n")({
7+
component: App,
8+
});
9+
10+
function App() {
11+
return (
12+
<div className="text-center">
13+
<header className="min-h-screen flex flex-col items-center justify-center bg-[#282c34] text-white text-[calc(10px+2vmin)] gap-4">
14+
<img
15+
src={logo}
16+
className="h-[40vmin] pointer-events-none animate-[spin_20s_linear_infinite]"
17+
alt="logo"
18+
/>
19+
<p>{m.example_message({ username: "TanStack Router" })}</p>
20+
<a
21+
className="text-[#61dafb] hover:underline"
22+
href="https://inlang.com/m/gerre34r/library-inlang-paraglideJs"
23+
target="_blank"
24+
rel="noopener noreferrer"
25+
>
26+
{m.learn_router()}
27+
</a>
28+
<div className="mt-3">
29+
<LocaleSwitcher />
30+
</div>
31+
</header>
32+
</div>
33+
);
34+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "Paraglide (i18n)",
3+
"description": "i18n with localized routing",
4+
"phase": "add-on",
5+
"modes": ["file-router"],
6+
"type": "add-on",
7+
"priority": 30,
8+
"link": "https://github.com/paraglidejs/paraglide-js",
9+
"routes": [
10+
{
11+
"icon": "Languages",
12+
"url": "/demo/i18n",
13+
"name": "I18n example",
14+
"path": "src/routes/demo.i18n.tsx",
15+
"jsName": "I18nDemo"
16+
}
17+
],
18+
"integrations": [
19+
{
20+
"type": "header-user",
21+
"path": "src/components/LocaleSwitcher.tsx",
22+
"jsName": "ParaglideLocaleSwitcher"
23+
}
24+
]
25+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"devDependencies": {
3+
"@inlang/paraglide-js": "^2.8.0"
4+
}
5+
}
Lines changed: 4 additions & 0 deletions
Loading

frameworks/react-cra/add-ons/start/assets/src/router.tsx.ejs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { HttpLink } from "@apollo/client";
1111
<% } %>
1212
<% if (addOnEnabled.sentry) { %>
1313
import * as Sentry from "@sentry/tanstackstart-react";
14+
<% } %><% if (addOnEnabled.paraglide) { %>
15+
import { deLocalizeUrl, localizeUrl } from "./paraglide/runtime";
1416
<% } %>
1517

1618
// Import the generated route tree
@@ -41,6 +43,13 @@ export const getRouter = () => {
4143
...rqContext,
4244
<% } %>
4345
},
46+
<% if (addOnEnabled.paraglide) { %>
47+
// Paraglide URL rewrite docs: https://github.com/TanStack/router/tree/main/examples/react/i18n-paraglide#rewrite-url
48+
rewrite: {
49+
input: ({ url }) => deLocalizeUrl(url),
50+
output: ({ url }) => localizeUrl(url),
51+
},
52+
<% } %>
4453
<% if (addOnEnabled['tanstack-query'] || addOnEnabled['apollo-client']) { %>
4554
defaultPreload: "intent",
4655
<% } else { %>

0 commit comments

Comments
 (0)