Creating a suitable Next.js sample to try out Gitloc
If you want to create your project from scratch, then you can use the following step-by-step guide, where we will create a multilingual Next.js sample project using next-intl and Gitloc
Make sure you have Node.js and npm installed. You’ll need to have Node.js 18.17 or later on your local development machine. You can use nvm (macOS/Linux), nvm-windows or volta to switch Node versions between different projects.
It's best, if you have some experience with simple HTML, JavaScript and basic Next.js, before jumping to localization. This localization example is not intended to be a Next.js beginner tutorial.
Now let's create a new Next.js project with create-next-app.
To create a new app, you may choose one of the following methods:
npx create-next-app@latest
yarn create next-app
pnpm create next-app
bunx create-next-app
You will then be asked the following prompts:
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
In this sample project we will use App Router. The Next.js App Router introduces support for React Server Components and unlocks many benefits when handling internationalization on the server side.
After the prompts, create-next-app will create a folder with your project name and install the required dependencies.
Once the installation is done, you can open your project folder:
cd my-app
Inside the newly created project, you can run the development server:
Run npm run dev to start the development server.
Visit http://localhost:3000 to view your application.
Edit app/page.tsx (or pages/index.tsx) file and save it to see the updated result in your browser.
In our example, we will create a project using App Router with 2 languages and separate files for translations.
next-intl integrates with the App Router, by using a [locale]dynamic segment so that we can use this segment to provide content in different languages (e.g. /en, /en/about, etc.).
Let's get started!
Run npm install next-intl and create the following file structure:
The middleware matches a locale for the request and handles redirects and rewrites accordingly.
middleware.ts
import createMiddleware from 'next-intl/middleware';
export default createMiddleware({
// A list of all locales that are supported
locales: ['en', 'de'],
// Used when no locale matches
defaultLocale: 'en'
});
export const config = {
// Match only internationalized pathnames
matcher: ['/', '/(de|en)/:path*']
};
app/[locale]/layout.tsx
The locale that was matched by the middleware is available via the locale param and can be used to configure the document language.
app/[locale]/layout.tsx
import {notFound} from 'next/navigation';
// Can be imported from a shared config
const locales = ['en', 'de'];
export default function LocaleLayout({children, params: {locale}}) {
// Validate that the incoming `locale` parameter is valid
if (!locales.includes(locale as any)) notFound();
return (
<html lang={locale}>
<body>{children}</body>
</html>
);
}
app/[locale]/page.tsx
Use translations in your page components or anywhere else!
app/[locale]/page.tsx
import {useTranslations} from 'next-intl';
export default function Index() {
const t = useTranslations('Index');
return <h1>{t('title')}</h1>;
}
That's all it takes!
Add translations usage
As you may have already noticed, changing the locale in the URL allows you to translate the page component using the provided t function. You will get the t function by using the useTranslation hook.
Now let's make the app more user-friendly and add some content to translate.
Copy the content from default page app/page.tsx to our localized page app/[locale]/page.tsx and add the t function from the useTranslation hook to it.
app/[locale]/page.tsx
import Image from 'next/image'
import styles from './page.module.css'
import {useTranslations} from 'next-intl';
export default function Index() {
const t = useTranslations('Index');
return <main className={styles.main}>
<div className={styles.description}>
<h1>{t('title')}</h1>
...
// rest from app/page.tsx
...
</div>
</main>;
}
Also copy the default page styles from app/page.module.css to app/[locale]/page.module.css or import them from outside.
Define a simple language switcher for our localized layout:
app/[locale]/layout.tsx
import Link from 'next/link';
import { notFound } from 'next/navigation';
import styles from './layout.module.css'
// Can be imported from a shared config
const locales = ['en', 'de'];
function LanguageSwitcher({ locale }) {
return (
<div className={styles.switcher}>
{locales.map((lng) => (
<Link
key={lng}
href={`${lng}/`}
className={`${styles.link} ${locale === lng && styles.current}`}
>
{lng}
</Link>
))}
</div>
);
}
export default function LocaleLayout({ children, params: {locale} }) {
// Validate that the incoming `locale` parameter is valid
if (!locales.includes(locale as any)) notFound();
return (
<html lang={locale}>
<body>
<LanguageSwitcher locale={locale} />
{children}
</body>
</html>
);
}
Now we have all the texts using translations, and we will see that this works if we add de.json and go to /de locale (this step can be done automatically once Gitloc is configured).
messages/de.json
{
"Index": {
"title": "Hallo Welt!",
"getStarted": "Erste Schritte durch Bearbeiten von <page>path</page>",
"links": {
"by": "Von <vercel>Vercel</vercel>",
"docs": {
"title": "Dokumentation",
"message": "Finden Sie ausführliche Informationen zu den Funktionen und der API von Next.js."
},
"learn": {
"title": "Lernen",
"message": "Erfahren Sie mehr über Next.js in einem interaktiven Kurs mit Quizfragen!"
},
"templates": {
"title": "Vorlagen",
"message": "Entdecken Sie Starter-Vorlagen für Next.js."
},
"deploy": {
"title": "Bereitstellen",
"message": "Stellen Sie Ihre Next.js-Site sofort auf einer gemeinsam nutzbaren URL mit Vercel bereit."
}
}
}
}
Finally, сonnect your local project folder to your new repository on GitHub.