How I Built a Multilingual Next.js Website in 3 Days
A mobile app without a website is like a restaurant without a sign. You can have the best cuisine in the world, but no one will find you. When I realized TAMSIV needed a showcase website — landing page, pricing, FAQ, legal pages — I set myself an ambitious goal: 3 days, no more.
72 hours later, tamsiv.com was online. Multilingual (6 languages), responsive, with an animated hero, SEO-optimized pages, and a Lighthouse score of 94/100/100. Here's the full story of this sprint, the technical choices, the pitfalls, and what I would do differently.
Key takeaways:
- Next.js 16 with App Router is ideal for a high-performance multilingual showcase site
- Internationalization with next-intl must be configured from the start, not added later
- Always runnpm run buildlocally before deploying to Vercel
- Responsiveness requires more iterations than expected — allocate 30% of total time
- A Lighthouse score of 90+ is achievable in 3 days with the right architectural choices
Why Next.js rather than Gatsby, Astro, or plain HTML?
The choice of framework is not trivial. I considered several options:
- Static HTML/CSS: The simplest, but unmanageable for 6 languages and 20+ pages. Every modification would have to be replicated 6 times.
- Gatsby: Good for static sites, but the build time and aging plugin ecosystem put me off.
- Astro: Excellent for static content, but I knew I would need interactive components (auth, dashboard) later.
- Next.js 16: App Router, React Server Components, hybrid rendering (static + dynamic), native i18n. And most importantly, I know React — it's the same ecosystem as the TAMSIV mobile frontend.
The choice of Next.js was also driven by a practical reason: I knew the site would evolve beyond a simple showcase site. The QR code authentication system, the app dashboard, the admin panel — all of this requires a framework capable of managing dynamic, protected pages.
How to organize a 3-day sprint effectively?
Three days is short. Without planning, you'll spend the first day setting up your environment and reach the third day with no content. Here's how I broke down the sprint:
Day 1: Technical Foundations (10 hours)
The first day is entirely dedicated to the technical infrastructure. Nothing visible to the user, but everything else depends on it:
- Next.js 16 setup with TypeScript, App Router, Tailwind CSS 4
- Internationalization with
next-intl— 6 languages (FR, EN, DE, ES, IT, PT) configured from the start - Localized routing:
/fr/fonctionnalites,/en/features,/de/funktionen... each page has a translated URL - Base layout: Header, footer, responsive navigation, dark theme (#101922)
- Vercel configuration: Git repo connected, automatic preview deployments
Localized routing alone cost me 2 hours of configuration. With next-intl, each route must be declared with its slug translations. It's verbose but results in clean, SEO-friendly URLs in each language.
Day 2: Content and Design (12 hours)
The most intense day. This is where the site takes shape:
- Animated hero: Particle background on a dark #101922 background, with a main CTA. I used a Spline 3D scene for the main visual.
- Content pages: Use cases (4 scenarios), features (responsive grid), pricing (3 plans with feature comparison), FAQ (accordion)
- Copywriting: Each page in French first, then translated. The tone: direct, informal "tu" address, user benefit-oriented
- Responsive: Where I spent the most time. The feature grids (3 columns → 2 → 1) required 3 iterations. The animated hero on mobile required a static fallback for performance.
Day 3: SEO, Performance, and Deployment (8 hours)
The last day is dedicated to everything that makes the site "professional":
- Technical SEO:
generateMetadata()per page with Open Graph, alternate languages, dynamic XML sitemap - Analytics: GA4 with RGPD Consent Mode (no tracking without consent)
- Legal pages: Legal notice, privacy policy, terms of service, cookies
- Performance: Image optimization, lazy loading, preloading critical fonts
- Vercel Deployment: And then... the battle.
Why did the first Vercel deployment fail?
The moment of truth. git push, the Vercel build starts... and fails. TypeScript error. Then another. Then a third.
What happened: in local development, Next.js is tolerant of certain type errors. The production build (next build) is strict. Implicit any types, missing imports, unhandled optional props — all of this passes in dev and breaks in prod.
The lesson, learned the hard way: always run npm run build locally before pushing. It takes 30 seconds and avoids 3 hours of debugging on Vercel logs (which are less readable than local output).
The most common errors I fixed:
- Implicit types:
function Component({ data })→function Component({ data }: { data: DataType }) - Unused imports: The build treats them as errors, not warnings
- Environment variables:
NEXT_PUBLIC_prefix required for client-side accessible variables - Alternates metadata: URLs for each language must be absolute, not relative
How to configure internationalization with next-intl from the start?
i18n was the topic that took me the most time on day 1. With next-intl, the initial setup requires rigor:
- Message files: One JSON file per language (
messages/fr.json,messages/en.json...). Identical structure, identical keys, translated values. - Middleware: Automatic browser language detection, redirection to the correct prefix (
/fr/,/en/). - Routing: Each page is in a
[locale]folder. Slugs are translated via a mapping file. - Components:
useTranslations('section')to access translations in each component.
The classic trap: starting without i18n and adding it later. I've seen projects where this cost weeks of refactoring. By implementing it on day 1, every component is already ready for 6 languages. Automatic translation via LLM then takes care of it.
An important point: the blog's HTML content is stored in separate files (content/blog/{locale}/{slug}.html), not in the JSON files. Why? Because next-intl interprets HTML tags as ICU variables and generates errors. This separation saved me hours of debugging.
How to get a Lighthouse score of 90+ with Next.js?
The final Lighthouse score: 94 Performance, 100 Accessibility, 100 SEO. Here are the key optimizations:
- Optimized images: Next.js
<Image>component withsizesandpriorityfor LCP. Automatic WebP format. - Critical fonts:
next/fontfor Google Fonts withdisplay: swap. Zero layout shift. - Lazy loading: All below-the-fold components loaded on demand. The animated hero is the only one loaded immediately.
- Atomic CSS: Tailwind CSS 4 generates minimal CSS — only used classes are included.
- Static Generation: All content pages are pre-rendered at build time. Zero server at runtime for static content.
The most critical performance point was the animated hero. The particle animation on a dark background was beautiful but heavy. I had to implement a threshold: on mobile, the animation is replaced by a static gradient. On desktop, it only starts after the LCP (Largest Contentful Paint).
What pages are essential for a mobile app showcase site?
For a launch, you don't need 50 pages. Here's the minimum viable I created in 3 days:
- Landing page: Hero + use cases + features + pricing + FAQ + CTA. This accounts for 80% of traffic.
- About: Who is behind the project. For a solo dev, it's a credibility asset.
- Privacy Policy: Mandatory for the Play Store and RGPD.
- Terms of Service: Mandatory for in-app subscriptions.
- Cookie Policy: Mandatory with the RGPD cookie consent.
- Blog: Optional at launch, but I set up the structure on day 3. The blog has become a major SEO acquisition channel.
Each page exists in 6 languages thanks to i18n. That's 30+ pages generated from 6 templates. The effort/impact ratio of i18n is enormous — I discuss it in detail in my article on i18n as an acquisition channel.
How has the site evolved since the initial sprint?
The 3 days laid the foundations. Since then, the site has evolved considerably:
- Dashboard app (
/app/tasks,/app/memos,/app/agenda): Complete web interface to manage tasks and memos from a browser. Authentication via QR code or email. - Admin panel (
/admin/dashboard): User metrics, Recharts graphs, alerts. Detailed in the article on the admin dashboard. - SEO Blog: 40+ technical articles optimized for search engines, with AI-generated images.
- Public Roadmap: Roadmap page with delivered and upcoming features.
- User Guide: Interactive documentation for new users.
None of this would have been possible without the solid foundations of the first 3 days. Next.js's App Router, native i18n, automatic Vercel deployment — each building block laid at the beginning facilitated subsequent additions.
What advice for a solo dev launching their site in a sprint?
If you're a solo dev and want to launch a showcase site quickly, here are my 5 recommendations:
- Choose a framework you know: This is not the time to learn. Use what you master.
- Configure i18n on day 1: Even if you only translate into one language, the structure is in place. Adding translations later will be trivial.
- Build locally before each push:
npm run build. Systematically. Without exception. - Mobile first for CSS: Start with mobile, add desktop breakpoints. The reverse always costs more time.
- Ship early, iterate later: An imperfect site online is better than a perfect site that only exists on localhost. Corrections will come.
FAQ
How much does it cost to host a Next.js site on Vercel?
The free plan of Vercel is sufficient for most showcase sites. It includes SSL, global CDN, and preview deployments. I still use the free plan for tamsiv.com, even with 40+ pages and regular traffic.
Should I use Tailwind CSS or another CSS framework?
Tailwind CSS is ideal for a quick sprint. You code the design directly in the JSX, no need for separate CSS files. The downside: the HTML code is verbose. But for a solo dev who wants to move fast, the readability overhead is largely offset by development speed.
How to manage translations without a professional translator?
I use an automatic translation script via OpenRouter (LLM). The script detects modified keys (delta-only), translates only what has changed, and costs about 0.05 EUR per pass. The quality is very good for technical texts. Details are in the article on i18n in 6 languages.
Is SEO sufficient with Next.js's generateMetadata?
generateMetadata() handles the title, description, Open Graph, and alternates (hreflang). This is sufficient for 90% of on-page SEO needs. I added a dynamic sitemap and a robots.txt for crawling. The rest (backlinks, content, authority) depends on the blog and marketing.
Can the same sprint be done with Astro instead of Next.js?
Yes, Astro would even be faster for a purely static site. But if you plan to add dynamic pages (auth, dashboard) later, Next.js remains the best choice. The transition from static to dynamic is seamless with the App Router.