Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Language Selector Checkout Block for React

A last checkout step in four languages: a select rewrites the labels and button, flips the panel right to left for Arabic, and shows the order total, a delivery date and a phone number in that language's own format.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Let people finish an order in their own language, with this language-selector checkout for React with Base UI. A compact header from Thornfold, a shop that prints local maps, ends in a labelled Native Select of four languages (English, Español, Français, العربية), each in its own script. Choosing one rewrites every word of the panel from one typed dictionary: the order, the email label and its problems, the button and the result. For Arabic the panel takes dir="rtl" and the Direction provider, so the layout mirrors, while the select keeps its own place. The order's three lines are shown in the language's currency from typed example rates, each converted to whole cents and then added, and a "Formatted for you" list shows the currency, a fixed delivery date and a phone number the way that language writes them, all through Intl. Lines that change sit over unseen copies of their other versions, so nothing under them moves. Place order is the only Shine Button. It's built from Native Select, Direction, Field, Input, Shine Button and Guides, with a CSS entrance only. For shops that sell in more than one language.

FAQ

Does it translate the page for me?

No. Every word in each language is typed into the ENGLISH, SPANISH, FRENCH and ARABIC dictionaries at the top of the file, and nothing calls a translation service. Add a language by adding one more Words object to LANGUAGES; the select, the cell heights and the formatting follow. Have a native speaker review the wording before you ship it, because the sentences here are short examples, not a vetted translation.

What changes for a right-to-left language?

The panel gets dir="rtl" and lang="ar", and its direction provider flips the controls that read it. The layout uses logical classes only, so rows mirror without separate styles. Prices, the email and the phone number stay left to right inside their own dir="ltr" spans, as a mixed line should, and the amounts use Latin digits so they match the keyboard the visitor types on. The language select itself stays left to right so it never jumps when the page flips.

Where do the prices in other currencies come from?

From a typed example rate for each language (0.92 for the euro, 1.37 for the Canadian dollar, 3.67 for the dirham), shown on the page as an example, not a quote. Each line is converted to whole cents and rounded once, then the lines are added, so the total always equals the sum of the lines you see. For real prices, keep one price per currency in your catalogue or fetch a rate on your server, and never convert in the browser.

Why do dates and numbers show dashes for a moment?

Intl can print the same date or currency slightly differently on the server and in the browser, which would break hydration. The block therefore draws dashes first and formats after it mounts. The delivery date is a fixed day in October 2026 and is never worked out from the clock.

Does changing the language move anything on the page?

No. Every line that changes (the order's item names, the status line) sits in a grid cell with unseen copies of its other versions, so the cell is as tall as the longest language. The button keeps its size, the problem line under the email is always rendered, and focus stays on the select while you choose.

What stays local in the demo, and how do I wire it up?

Everything. The language lives in the block's state, the rates are constants and Place order only waits 700 ms and says that nothing was charged. In your app, take the language from the route or the visitor's saved preference, load your translations from your own files, create the order on your server with the currency you priced it in, and show the server's error in the same status line.