# `PhoenixKit.Migrations.Postgres.V28`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.87/lib/phoenix_kit/migrations/postgres/v28.ex#L1)

Migration V28: Add preferred_locale field to users table for dialect preferences.

This migration adds support for user-specific language dialect preferences,
allowing authenticated users to choose their preferred variant (e.g., en-GB vs en-US)
while URLs continue to show simplified base language codes (/en/ instead of /en-US/).

## Changes
- Adds `preferred_locale` column to `phoenix_kit_users` table (nullable string, size 10)
- Creates index on `preferred_locale` for potential locale-based queries
- Supports full dialect codes (en-US, es-MX, zh-Hans-CN, etc.)

## Requirements
- PostgreSQL database
- PhoenixKit V27 or higher

## Purpose
Enable simplified URL structure with dialect preferences:
- URLs show base codes: `/en/`, `/es/`, `/fr/`
- Users can save preferred dialects: "en-GB", "es-MX", "pt-BR"
- Guest users get default dialect mapping (en → en-US)
- Translation system uses full dialect codes internally

## Usage
Once migrated, users can update their locale preference:

    PhoenixKit.Users.Auth.update_user_locale(user, "en-GB")

When visiting `/en/dashboard`, the system will:
1. Detect base code "en" from URL
2. Resolve to user's preferred_locale ("en-GB")
3. Use "en-GB" for translations while URL stays `/en/`

## Validation
- Format validation: matches ~r/^[a-z]{2}(-[A-Z]{2})?$/
- Existence validation: must be in predefined language list
- NULL allowed: defaults to system dialect mapping

## Size Rationale
- Size 10 supports extended codes like "zh-Hans-CN" (10 chars)
- Covers all standard language-REGION codes (5 chars: "en-US")
- Allows future BCP 47 extensions if needed

## Notes
- Idempotent: Safe to run multiple times
- No default value: NULL indicates "use system default"
- Index improves potential analytics queries
- Backward compatible: existing users have NULL (use defaults)

# `down`

# `up`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
