Init
This commit is contained in:
180
tasks/10-i18n.md
Normal file
180
tasks/10-i18n.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# Phase 10: i18n (Internationalization)
|
||||
|
||||
**Status:** ⏳ Todo
|
||||
**Progress:** 0/8 tasks (0%)
|
||||
**Started:** -
|
||||
**Completed:** -
|
||||
**Assigned to:** -
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Implement internationalization (i18n) with @nuxtjs/i18n: support German (default) and English, translate all UI strings, and create language switcher.
|
||||
|
||||
**Goal:** App is fully bilingual (German + English) with proper routing and formatting.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- ✅ Phase 1-9: Most UI components should be created by now
|
||||
|
||||
---
|
||||
|
||||
## Tasks
|
||||
|
||||
### Setup
|
||||
|
||||
- [ ] Install @nuxtjs/i18n
|
||||
|
||||
```bash
|
||||
pnpm add @nuxtjs/i18n
|
||||
```
|
||||
|
||||
- [ ] Configure i18n module
|
||||
- File: `nuxt.config.ts`
|
||||
```typescript
|
||||
export default defineNuxtConfig({
|
||||
modules: ['@nuxtjs/i18n'],
|
||||
i18n: {
|
||||
locales: [
|
||||
{ code: 'de', iso: 'de-DE', name: 'Deutsch', file: 'de-DE.json' },
|
||||
{ code: 'en', iso: 'en-US', name: 'English', file: 'en-US.json' },
|
||||
],
|
||||
defaultLocale: 'de',
|
||||
strategy: 'prefix_except_default',
|
||||
langDir: 'locales',
|
||||
lazy: true,
|
||||
detectBrowserLanguage: {
|
||||
useCookie: true,
|
||||
cookieKey: 'i18n_redirected',
|
||||
redirectOn: 'root',
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Translation Files
|
||||
|
||||
- [ ] Create locale files (de-DE.json, en-US.json)
|
||||
- Create: `locales/de-DE.json` (German)
|
||||
- Create: `locales/en-US.json` (English)
|
||||
- Structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"common": {
|
||||
"header": { "home": "Startseite", "products": "Produkte", ... },
|
||||
"footer": { ... },
|
||||
"buttons": { "submit": "Absenden", "cancel": "Abbrechen", ... }
|
||||
},
|
||||
"auth": {
|
||||
"login": { "title": "Anmelden", "email": "E-Mail", ... },
|
||||
"register": { ... }
|
||||
},
|
||||
"products": { ... },
|
||||
"cart": { ... },
|
||||
"checkout": { ... },
|
||||
"errors": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] Translate all UI strings
|
||||
- Go through all components and pages
|
||||
- Replace hardcoded German strings with `$t('key')` or `t('key')`
|
||||
- Add translations to both de-DE.json and en-US.json
|
||||
- Components to translate:
|
||||
- Header, Footer
|
||||
- Auth forms (Login, Register)
|
||||
- Product list, Product detail
|
||||
- Cart, CartItem, CartSummary
|
||||
- Checkout form
|
||||
- PayPal button texts
|
||||
- Error messages
|
||||
- Success messages
|
||||
- Validation messages (VeeValidate)
|
||||
|
||||
### UI Components
|
||||
|
||||
- [ ] Create language switcher component
|
||||
- File: `components/Common/LanguageSwitcher.vue`
|
||||
- Dropdown or toggle: 🇩🇪 Deutsch | 🇬🇧 English
|
||||
- Uses: `$i18n.locale` and `$switchLocalePath()`
|
||||
- Place in header
|
||||
- Styling: shadcn-nuxt DropdownMenu or simple buttons
|
||||
|
||||
### Testing
|
||||
|
||||
- [ ] Test route localization
|
||||
- Visit /produkte (German)
|
||||
- Switch to English → should redirect to /en/products
|
||||
- Test all main routes:
|
||||
- / → /en/ (homepage)
|
||||
- /produkte → /en/products
|
||||
- /warenkorb → /en/cart
|
||||
- /kasse → /en/checkout
|
||||
- Verify route parameters preserved (/produkte/[id] → /en/products/[id])
|
||||
|
||||
- [ ] Test currency/date formatting
|
||||
- Use Intl.NumberFormat for currency (EUR)
|
||||
- Use Intl.DateTimeFormat for dates
|
||||
- Example in component:
|
||||
|
||||
```typescript
|
||||
const { locale } = useI18n()
|
||||
const formatPrice = (price: number) => {
|
||||
return new Intl.NumberFormat(locale.value, {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
}).format(price)
|
||||
}
|
||||
```
|
||||
|
||||
- Test: German → "19,99 €", English → "€19.99"
|
||||
|
||||
- [ ] Document i18n structure
|
||||
- Document translation file structure
|
||||
- Document how to add new translations
|
||||
- Document naming conventions for translation keys
|
||||
- Document how language switcher works
|
||||
- Document how to format currency/dates per locale
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] @nuxtjs/i18n is installed and configured
|
||||
- [x] Locale files exist for German and English
|
||||
- [x] All UI strings are translated (no hardcoded German text)
|
||||
- [x] Language switcher component is functional
|
||||
- [x] Can switch between German and English
|
||||
- [x] Routes change with language (/produkte ↔ /en/products)
|
||||
- [x] Currency formatting respects locale
|
||||
- [x] Date formatting respects locale
|
||||
- [x] i18n structure is documented
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **Default Language:** German (de)
|
||||
- **Route Strategy:** prefix_except_default (German has no prefix, English has /en/)
|
||||
- **SEO:** Automatic hreflang tags for SEO
|
||||
- **Lazy Loading:** Translation files loaded on demand
|
||||
- **Browser Detection:** Redirects to browser language on first visit (if supported)
|
||||
|
||||
---
|
||||
|
||||
## Blockers
|
||||
|
||||
- None currently
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [docs/PRD.md: Bilingual Support](../docs/PRD.md#bilingual-support)
|
||||
- [docs/TECH_STACK.md: i18n](../docs/TECH_STACK.md#9-internationalization-i18n)
|
||||
- [CLAUDE.md: Important Constraints](../CLAUDE.md#important-constraints)
|
||||
- [@nuxtjs/i18n Docs](https://i18n.nuxtjs.org/)
|
||||
Reference in New Issue
Block a user