Instant chat and full German localization
- Improved
- Fixed

Two of the most interaction-heavy parts of the kit, the locale switcher and AI chat, no longer pay a server round-trip on every action. And the German locale is now something you can actually ship to German customers.
Locale switching is instant
Switching languages used to go through a Server Action that wrote cookies, persisted the preference to the database, and blocked on a full revalidation before anything changed. The client now owns the cookie and navigates immediately through the next-intl router, while database persistence is deferred until after the response. A tab-scoped queue serializes those writes and keeps only the latest locale while a request is in flight, with retries on failure, so the stored preference cannot silently desync from what you see. The preference still lands on the user record, which continues to drive transactional email language.
Chat navigation is instant too
The chat page became a client page backed by prefetched shells, so switching between conversations no longer waits on a server render. Creating a chat reserves its id before the create call and warms the route, so the first navigation into a new conversation has no server wait either, and an in-flight create is awaited before auto-sending the first message, closing a not-found race.
History is also protected against a subtler class of bugs where messages could be dropped or reordered by a slow refetch after navigating away and back. Optimistic messages reconcile against the server when streams finish, refreshed history is only adopted when it structurally contains what you already see, and merges are ordered around local state. On the server, the client-generated user message id is validated and persisted as the row id, and one assistant message id per turn is used in both the UI stream and the database, so message identity is stable end to end.
German that reads like German
The German locale got a full rewrite. Awkward machine-translated strings across marketing and dashboard were redone, and surfaces that were still hardcoded English are now wired through next-intl: navigation labels in the sidebar, user menu, and command palette, plus pricing, contact, the blog pages and forms, the hero band, and chat toasts. Five German blog posts ship alongside the English ones, with the blog list and post pages selecting content by locale, and the sitemap is locale-aware. Open Graph and Twitter metadata are localized as well, so a shared /de link previews in German.