Magic Translate vs. next-intl
next-intl is the most widely used i18n library for Next.js. It works with the App Router and React Server Components, and is built around message files with a key for every text. Magic Translate also renders fully translated pages on the server, but you write your text directly in your components, and the translations are created for you.
At a glance
| Magic Translate | next-intl | |
|---|---|---|
| How you write text | Your own words, wrapped in <T> | A key per text, such as t('title') |
| Translations | AI translation, created automatically | You or your translators write them |
| Message files | None | One JSON file per language |
| New languages | Add the locale to your list | Translate every message into the new language |
| Server rendering | React Server Components, fully translated HTML | React Server Components, fully translated HTML |
| Locale routing | Use a [locale] segment | Built-in routing and middleware |
| Price | Free plan, then monthly plans based on usage | Open source and free |
How the code differs
With next-intl, you keep a message file for each language and refer to the texts by key:
// messages/en.json{ "HomePage": { "title": "Welcome to our website" } }// app/[locale]/page.tsximport { getTranslations } from 'next-intl/server';export default async function HomePage() {const t = await getTranslations('HomePage');return <h1>{t('title')}</h1>;}
With Magic Translate, the text stays in the page:
// app/[locale]/page.tsximport { createLocalizedT } from '@magic-translate/react-ssr';import { translate } from '@/lib/translate';export default async function HomePage({params}: {params: Promise<{ locale: string }>;}) {const { locale } = await params;const { T } = createLocalizedT(translate, locale);return (<h1><T>Welcome to our website</T></h1>);}
The Next.js guide shows the full setup.
When to choose Magic Translate
- You want your Next.js site in many languages without maintaining message files.
- Your texts change often, and you want every language to stay up to date.
- You don't have translators, or you don't want to wait for them before you release.
When to choose next-intl
- Every text must be translated or reviewed by a person.
- You need exact control over plurals, dates and numbers with ICU messages.
- You want a free, open-source library with no external service.
Using both
You can keep next-intl for its locale routing and formatting, and use Magic Translate for the text. Pass the locale from next-intl to createLocalizedT, and move one page at a time from keys to <T>.
Ready to try it? Follow the getting started guide to translate your first component in five minutes.