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 each message. 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 for each message, 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 each message by its 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 text changes often, and you want every language to stay up to date.
- You don't have translators, or you want to release updates without waiting for translations.
When to choose next-intl
- All 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 replace keys with <T> one page at a time.
Ready to try it? Follow the getting started guide to translate your first component in five minutes.