Woovi master plan is to learn a lot about instant payments at Brazil, and be the best platform of instant payments in the world.
For this to happen everything that we build needs to support multi-languages.
One place that was missing multi-language support was in our landing page that uses Next.js.
Static website with Next.js
Even though Next.js is know because of their server side capabilities, our landing page is just a static website.
We use next export
to build our landing page and deploy to CloudFlare Pages and CloudFront.
Next has support to i18n out of the box, but not yet when using next export
. So we need to figure it out the solution ourselves.
Our landing page architecture
We build our landing page using two approaches: tsx and MDX.
When a page has many different styles and customization, we built it using React/tsx. Example: https://woovi.com/shopper/
<Typography>
{t('Create your free account now')}
</Typography>
For tsx we mainly use t()
to translate string literals.
When a page is more about content, like an article, it is written in MDX. MDX is Markdown with support to React components. Example: https://woovi.com/articles/a-woovi-e-a-primeira-plataforma-pix-first-do-mundo/
import { ArticleLayout } from '../../templates/ArticleLayout';
export const meta = {
title: "Pix Débito Automático - Cobrança Pix com Débito Automático",
}
## Módulo para cobranças automáticas usando Pix
O módulo Woovi
export default ({ children }) => <ArticleLayout meta={meta}>{children}</ArticleLayout>;
For mdx we don't translate using t()
because this is a full text, and translation of word by word does not provide a good translation.
When adding multi-language support we need to take this architecture in consideration.
Our approach to Multi-language using Next.js
To make our landing page multi-language we have the following structure:
pages/
pages/en
pages/<another-language>
pages/ is our default language, Portuguese.
We duplicate all the pages inside pages/
to all the languages we are supporting, right now only en
, English.
For tsx
files it will be translate using t()
.
For mdx
files we duplicate and translate the whole content at once.
We check the pathname of the router to determine what language the page is:
const defaultLang = 'ptBR';
export const getLangFromPathname = (pathname: string) => {
const langs = ['en', 'ptBR'];
for (const lang of langs) {
if (pathname.startsWith(`/${lang}`)) {
return lang;
}
}
return defaultLang;
}
Inside _app.tsx
we have this code to make provide the language from the pathname to a React context
const MyApp = ({ Component, pageProps, router }: NextAppProps<AppProps>) => {
const lang = getLangFromPathname(router.pathname);
const { t } = useTranslation(lang);
return (
<I18Context.Provider value={{ lang }}>
{getLayout(<Component {...pageProps} />, { t })}
</I18Context.Provider>
)
}
Our custom useTranslation
hook reads the language from the context and return the correct t()
.
export const useI18n = () => {
return useContext(I18Context) || {};
};
export const useTranslation = (defaultLang = 'ptBR') => {
const { lang = defaultLang } = useI18n();
const t: TFunction = (key) => {
const langs = {
ptBR,
en,
};
const trans = langs[lang][key];
if (!trans) {
if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
console.log('Missing translation: ', key);
}
}
return trans;
};
return { t };
};
Link is another thing that needs to be fixed in a multi-language website.
We created the hook useHrefLang
to return the correct href based on current language
export const useHrefLang = (href: string) => {
const { lang = defaultLang } = useI18n();
if (href?.startsWith('https://')) {
return href;
}
if (href?.startsWith('http://')) {
return href;
}
if (lang === defaultLang) {
return href;
}
if (href?.startsWith(`/${lang}`)) {
return href;
}
return `/${lang}${href}`;
};
In Conclusion
There are much more engineering in a landing page than it looks like.
A multi-language landing page takes more time to maintain, so make sure is the right moment for you to have one.
Check the final result here: https://woovi.com/en
Woovi
Woovi is a Startup that enables shoppers to pay as they like. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.
If you want to work with us, we are hiring!
Photo by Kalen Emsley on Unsplash
Top comments (2)
Hello. Where do you use useHrefLang hook?
Did you use 'next export'?
Can you share a link to a git repo with the full example please?
You can use like this
const link = '/products';
const linkLanguageAware = useHrefLang(link);
linkLanguageAware
would be like this based on the languages, examples: