Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Language Selector Login Block for React Aria

A full-height sign-in page that speaks six languages: a select of native names rewrites every word from one typed dictionary, and Arabic flips the whole card to right to left.

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 sign in in their own language, with this language selector login block for React with React Aria. It's the sign-in of Polyglade, a language-exchange app: the page's side rails run the full height of the screen and one band crosses it between two rules. A Select at the end of the first row lists English, Español, Français, Deutsch, 日本語 and العربية, each in its own script, and choosing one rewrites every word of the page from one typed dictionary: the heading, the sentence, the labels, the link, the button, each problem and the result. The card carries the language's lang, and Arabic lays it out from its end, through dir on the card and the catalog Direction Provider, while the select keeps its place and its focus. Below sit a Field with an Input for the email, another with a Password Input and the Shine Button, the only colored control. Every line that changes sits over unseen copies of its other versions in one cell, so nothing resizes. It's built from Select, Direction Provider, Field, Input, Password Input, Button, Shine Button and Guides, with a CSS entrance only. For apps with an international audience.

FAQ

What stays in the page, and how do I translate for real?

The dictionary is a typed array in the page, about nineteen strings for each of the six languages, and no translation service is called. Sign-in waits under a spinner for less than a second, then shows the result in the chosen language and a polite status message says nothing was sent. In a product, load your strings with your i18n library, choose the first language from the Accept-Language header or the user's saved setting, and keep the select as the way to change it. Post the form to your auth endpoint where the code says so.

What does choosing Arabic change?

The card gets dir="rtl" and lang="ar", and the catalog Direction Provider tells the controls inside to read from the end too, so the labels, the "Forgot password?" link, the show and hide button in the password field and the result list all mirror, using logical classes only. The language select sits in a left-to-right row that doesn't flip, so it stays where you pressed it, and keeps focus. What you type in the fields follows the text you type.

Why doesn't anything move when I change the language?

German is longer than English and Japanese is shorter. Each changing line (the heading, the sentence, the link) sits in one grid cell over unseen copies of its other versions, so the cell is as tall as the tallest, and the form under it never shifts. Problems stay short for the same reason, and the select's width doesn't depend on the language.

Why is the language select kept out of the form?

It changes the page, not the sign-in, so it has no business in what the form sends. Some bases also render hidden inputs for a select inside a form. It sits in its own row above the card, named in the current language ("Language", "Idioma", "اللغة"), and its items carry their own lang so they are pronounced correctly.

Is everything translated, including the show password button?

Everything in the dictionary is. The show and hide button inside the password field takes its name from the catalog, which is in English for now, so it carries lang="en" and a screen reader pronounces it as English rather than as the page's language. Until the catalog names it per language, that is the honest option; the visible icon needs no words.

How do I add a language?

Add an entry to LANGUAGES with its code, its name in itself (the autonym), every string, and rtl: true if it reads from the end. The select, the unseen copies that hold the height and the live message all follow from that one array. Keep each problem under about thirty characters so it fits its line on a phone.