Multi-Currency Store Setup with i18n in Next.js

by Sachin 3 minute read 7 views

Multi-currency Next.js stores enhance global sales by providing localized pricing, building user trust, increasing conversions, and faultlessly supporting international customers with real-time currency switching and translations.

Key Points

  • Multi-currency stores boost conversion rates by 30%, improving international sales performance.
  • Localized pricing increases customer trust, with 40% higher engagement in global markets.
  • Supporting multiple languages and currencies drives 25% more repeat purchases across regions.

In today’s borderless e-commerce world, creating an online store that supports multiple currencies is just as crucial as supporting multiple languages. If you’re using Next.js, combining i18n with multi-currency support ensures your store feels local to customers worldwide. Whether you’re developing custom apps or managing a global e-commerce platform, letting users pay in their local currency builds trust, increases conversions, and boosts customer satisfaction.

This guide takes you through a step-by-step setup for multi-currency support with i18n in a Next.js App Router project, making it easy to display products in currencies like USD, EUR, and IRR (Iranian Rial).

Step 1 – Install Required Packages

To get started, install next-intl for i18n along with a currency formatting library like Intl.NumberFormat (native to JavaScript).

                                        npm install next-intl
                                    

For custom currency formatting, you don’t need extra dependencies—JavaScript already provides powerful internationalization APIs.

Step 2 – Prepare Translation & Currency Files

Create a directory to hold locale JSON files along with a currency configuration.

Folder Structure:

                                        src/
  └── messages/
        ├── en.json
        └── fa.json
  └── currencies/
        └── config.ts
                                    

Example en.json:

                                        {
  "Header": {
    "cart": "Cart",
    "checkout": "Checkout",
    "currency_label": "Currency"
  },
  "Product": {
    "title": "Fresh Organic Apples",
    "description": "Crisp, juicy apples sourced directly from local farms."
  }
}
                                    

Currency Config (config.ts):

                                        export const currencyConfig = {
  USD: { locale: "en-US", currency: "USD" },
  EUR: { locale: "de-DE", currency: "EUR" },
  IRR: { locale: "fa-IR", currency: "IRR" }
};
                                    

This separation guarantees proper handling of both text translations and currency formats—a best practice in custom app development.

Step 3 – Configure Locale & Currency Detection

Detect the user’s preferred language and currency from cookies.

File: src/i18n/request.ts

                                        import { cookies } from "next/headers";
import { getRequestConfig } from "next-intl/server";
import { currencyConfig } from "@/currencies/config";

export default getRequestConfig(async () => {
  const cookieStore = await cookies();
  
  // Detect locale
  const locale = cookieStore.get("NEXT_LOCALE")?.value || "en";
  
  // Detect currency
  const currency = cookieStore.get("NEXT_CURRENCY")?.value || "USD";

  return {
    locale,
    messages: (await import(`../../messages/${locale}.json`)).default,
    currencyConfig: currencyConfig[currency]
  };
});
                                    

This setup guarantees that translations and currencies are loaded dynamically based on user preferences.

Step 4 – Update Root Layout with i18n & Currency Provider

Wrap your app with NextIntlClientProvider, providing both locale and currency configurations.

File: app/layout.tsx

                                        import type { Metadata } from "next";
import "./globals.css";
import { NextIntlClientProvider } from "next-intl";
import { getLocale } from "next-intl/server";
import { cookies } from "next/headers";
import { currencyConfig } from "@/currencies/config";

export const metadata: Metadata = {
  title: "Multi-Currency Store",
  description: "Global store with multiple currencies & languages"
};

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const locale = (await getLocale()) || "en";
  const currency = (await cookies()).get("NEXT_CURRENCY")?.value || "USD";

  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider locale={locale} messages={await import(`../messages/${locale}.json`)}>
          <CurrencyProvider currency={currencyConfig[currency]}>
            {children}
          </CurrencyProvider>
        </NextIntlClientProvider>
      </body>
    </html>
  );
}
                                    

Here, CurrencyProvider is a custom context you will create to manage currency state.

Step 5 – Build a Currency Switcher

Enable users to switch their currency instantly.

Component Example:

                                        "use client";
import { useState } from "react";

export default function CurrencySwitcher() {
  const [currency, setCurrency] = useState("USD");

  const handleCurrencyChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    const newCurrency = e.target.value;
    document.cookie = `NEXT_CURRENCY=${newCurrency}; path=/;`;
    window.location.reload();
  };

  return (
    <select value={currency} onChange={handleCurrencyChange}>
      <option value="USD">USD - US Dollar</option>
      <option value="EUR">EUR - Euro</option>
      <option value="IRR">IRR - Iranian Rial</option>
    </select>
  );
}
                                    

This dropdown allows users to change prices to their preferred currency quickly.

Step 6 – Format Prices in Components

Use Intl.NumberFormat with your set locale and currency.

Example: ProductCard.tsx

                                        "use client";
import { useTranslations } from "next-intl";
import { useCurrency } from "@/providers/CurrencyProvider";

const ProductCard = () => {
  const t = useTranslations("Product");
  const { locale, currency } = useCurrency();

  const price = new Intl.NumberFormat(locale, {
    style: "currency",
    currency: currency,
  }).format(5);

  return (
    <div className="product-card">
      <h2>{t("title")}</h2>
      <p>{t("description")}</p>
      <strong>{price}</strong>
    </div>
  );
};
                                    

export default ProductCard;

This makes sure that 5 is shown as $5.00, €5.00, or ریال 5 depending on the chosen currency.

Step 7 – Final Output

At this stage, your store:

  • Detects locale and currency automatically via cookies
  • Let users switch currencies through a dropdown
  • Formats product prices dynamically based on locale/currency
  • Supports scalable multi-language and multi-currency growth

This is invaluable for businesses, ranging from freelancers offering custom app development to an enterprise app development company serving global e-commerce clients.

Final Words

Supporting multiple currencies in a Next.js store boosts trust, usability, and conversions across global markets. By integrating i18n with currency handling, your app ensures customers see prices in their familiar currency while enjoying localized content.

Whether you’re running a startup store or a large-scale app development company, a multi-currency, multi-language setup future-proofs your application and maximizes global reach. Looking to expand internationally? Multi-currency support isn’t just a bonus—it’s essential for modern e-commerce success.

Tech Stack & Version

Frontend

  • Next.js
  • Tailwind CSS
  • Bootstrap

Backend

  • Node.js
  • PostgreSQL
  • MySQL

Deployment

  • AWS
  • DigitalOcean
img

©2025Digittrix Infotech Private Limited , All rights reserved.