#Using ParaglideJS with Next.js' Pages Router
In this guide you will learn how to internationalise your NextJS app that's using the Pages router with ParaglideJS!
By the end you will have i18n routing set up in an SEO friendly manner, be able to use translations in your code, all using ParaglideJS which ships some very compact JS thanks to it's compiler based approach.
This guide assumes that you already have a Next.js project set up with the pages router. If you don't, you can follow the official Next.js Getting Started Guide
#Install ParaglideJS
We will need to install two things. ParaglideJS itself, and Paraglide-Next.
ParaglideJS is the i18n library we will use for string translations. Paraglide-Next makes it easier to integrate Paraglide with NextJS's i18n routing.
In your project root, run the following commands and follow the instructions in your terminal.
npx @inlang/paraglide-js init npm install @inlang/paraglide-next
This will have done a few things:
- Created an inlang project in your project root
- Added the required devDependencies to your
package.json
- Added the paraglide compiler to your
package.json
build scripts - Installed the Paraglide-Next which will handle setting the locale
#Setting up
In your next.config.js
, import the Paraglide Plugin and apply it to your config.
You will need to pass it some config. The location of the Inlang Project & the output directory that messages should be compiled to. You should stick with the defaults unless you have a reason not to.
// next.config.js
const { paraglide } = require("@inlang/paraglide-next/plugin")
module.exports = paraglide({
paraglide: {
project: "./project.inlang",
outdir: "./src/paraglide"
}
})
This Plugin will make sure to automatically recompile messages whenever they change.
Next, let's set up NextJS' built in i18n routing.
Still in your next.config.js
, add the i18n
object to your config, pass it the languages you want to support and set the default language.
// next.config.js
const { paraglide } = require("@inlang/paraglide-next/plugin")
module.exports = paraglide({
paraglide: {
project: "./project.inlang",
outdir: "./src/paraglide"
},
i18n: {
locales: ["en", "de"], //list the languages you intend to support
defaultLocale: "en",
},
})
Last, let's add the <ParaglideJS>
component to your _app.js
file. This will manage the language state for you.
// _app.js
import type { AppProps } from "next/app"
import { ParaglideJS } from "@inlang/paraglide-next/pages"
export default function App({ Component, pageProps }: AppProps) {
return (
<ParaglideJS>
<Component {...pageProps} />
</ParaglideJS>
)
}
#Our first Message
Translations live in the messages/{lang}.json
files that were generated by the init CLI. Add messages there
// messages/en.jsons
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"hello_world": "Hello World!"
}
If you now start your app, you should see a new folder appear in your src
folder called paraglide
. This folder contains the compiled messages and any runtime code required by paraglide. Your messages live at ./src/paraglide/messages.js
.
Let's use the hello_world
message on our homepage. Open pages/index.js
, import from paraglide/messages.js
and use the hello_world
message in the h1
tag.
// @ is next's default alias for the src/ folder
// By convention paraglide uses import * as m
import * as m from "@/paraglide/messages"
export default function Home() {
return (
<div>
<h1>{m.hello_world()}</h1>
</div>
)
}
You should now see the message "Hello World!" on your homepage!
Note: If you are using Visual Studio Code, you should install the accompanying VS Code extension Sherlock. It will give you inline message previews & allow you to edit them right from your code.
#Adding more languages
You need to add more languages in two places. First, in your next.config.js
file, and then in your Inlang project settings.
Let's add german to both:
//next.config.js
module.exports = paraglide({
i18n: {
locales: ["en", "de"], // <-- Added german
defaultLocale: "en",
},
...
})
// project.inlang/settings.json
{
"$schema": "https://inlang.com/schema/project-settings",
"sourceLanguageTag": "en",
"languageTags": ["en", "de"], // <-- Added german
"...": "..."
}
You can now add a de.json
file to your messages
folder and add a german translation for the hello_world
message.
// messages/de.json
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"hello_world": "Hallo Welt!"
}
With this config in place, you should get the following routing behaviour:
/some-page
- Default language (English)/en/some-page
- English/de/some-page
- German
When you visit /de
you should now see the german translation of "Hello World!".
#Switching languages the right way
We will use a <Link>
to switch languages. This will automatically rerender the page and load the correct messages. You can specify the locale
prop to set which language to switch to.
// pages/index.js
import * as m from "@/paraglide/messages"
import Link from "next/link"
import { useRouter } from "next/router"
export default function Home() {
const router = useRouter()
return (
<div>
<h1>{m.hello_world()}</h1>
<Link href={router.asPath} locale="en" hrefLang="en">
English
</Link>
<Link href={router.asPath} locale="de" hrefLang="de">
German
</Link>
</div>
)
}
Alternatively, you could use Next's router.push
function to switch languages programmatically.
// pages/index.js
import * as m from "@/paraglide/messages"
import { useRouter } from "next/router"
export default function Home() {
const router = useRouter()
return (
<div>
<h1>{m.hello_world()}</h1>
<button onClick={() => router.push(router.asPath, router.asPath, { locale: "en" })}>
English
</button>
<button onClick={() => router.push(router.asPath, router.asPath, { locale: "de" })}>
German
</button>
</div>
)
}
You should always switch languages by doing a navigation. This will ensure that the correct messages are loaded and that the correct language is set in the url.
#Next Steps
That's it! You should now have a fully functional multilingual NextJS app using ParaglideJS. Wasn't that hard was it?
You can check out the full source code of this example here
If you want to learn more about ParaglideJS, check out the ParaglideJS Documentation. If you need help or have some ideas, feel free to reach out to us on Discord