diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..676b22c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,120 @@
+name: Bug Report
+description: Report a bug or unexpected behavior
+title: "[Bug]: "
+labels: ["bug"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to report a bug! Please fill out the information below to help us investigate.
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Describe the bug
+ description: A clear and concise description of what the bug is.
+ placeholder: What went wrong?
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Reproduction
+ description: Steps to reproduce the behavior, or a link to a minimal reproduction (CodeSandbox, StackBlitz, GitHub repo).
+ placeholder: |
+ 1. Configure i18n with...
+ 2. Navigate to...
+ 3. See error...
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected behavior
+ description: What did you expect to happen?
+ placeholder: What should have happened?
+ validations:
+ required: true
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual behavior
+ description: What actually happened?
+ placeholder: What actually happened?
+ validations:
+ required: true
+
+ - type: input
+ id: sveltekit-i18n-version
+ attributes:
+ label: sveltekit-i18n version
+ description: What version of sveltekit-i18n are you using?
+ placeholder: "2.4.2"
+ validations:
+ required: true
+
+ - type: input
+ id: sveltekit-version
+ attributes:
+ label: SvelteKit version
+ description: What version of SvelteKit are you using?
+ placeholder: "2.0.0"
+ validations:
+ required: true
+
+ - type: input
+ id: node-version
+ attributes:
+ label: Node.js version
+ description: What version of Node.js are you using?
+ placeholder: "20.10.0"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: adapter
+ attributes:
+ label: SvelteKit Adapter
+ description: Which SvelteKit adapter are you using?
+ options:
+ - "@sveltejs/adapter-auto"
+ - "@sveltejs/adapter-node"
+ - "@sveltejs/adapter-static"
+ - "@sveltejs/adapter-vercel"
+ - "@sveltejs/adapter-netlify"
+ - "@sveltejs/adapter-cloudflare"
+ - "Other (specify in additional context)"
+ validations:
+ required: true
+
+ - type: textarea
+ id: logs
+ attributes:
+ label: Error logs
+ description: Please paste any relevant error messages or console logs.
+ render: shell
+ placeholder: Paste error logs here
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional context
+ description: Add any other context about the problem here (browser, operating system, etc.).
+ placeholder: Any additional information that might help
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ description: Please confirm the following
+ options:
+ - label: I have searched existing issues to avoid duplicates
+ required: true
+ - label: I have provided a minimal reproduction (if possible)
+ required: false
+ - label: I have checked the [Troubleshooting Guide](https://github.com/sveltekit-i18n/lib/blob/master/docs/TROUBLESHOOTING.md)
+ required: false
+
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..aebcf96
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,15 @@
+blank_issues_enabled: false
+contact_links:
+ - name: ๐ฌ GitHub Discussions
+ url: https://github.com/sveltekit-i18n/lib/discussions
+ about: Ask questions, share ideas, or discuss the project
+ - name: ๐ Documentation
+ url: https://github.com/sveltekit-i18n/lib/tree/master/docs
+ about: Read the complete documentation
+ - name: ๐ง Troubleshooting Guide
+ url: https://github.com/sveltekit-i18n/lib/blob/master/docs/TROUBLESHOOTING.md
+ about: Common issues and solutions
+ - name: ๐ก Examples
+ url: https://github.com/sveltekit-i18n/lib/tree/master/examples
+ about: Working example applications
+
diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml
new file mode 100644
index 0000000..cf855fd
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation.yml
@@ -0,0 +1,69 @@
+name: Documentation Issue
+description: Report an issue with documentation or suggest improvements
+title: "[Docs]: "
+labels: ["documentation"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for helping improve our documentation!
+
+ - type: dropdown
+ id: doc-type
+ attributes:
+ label: Documentation type
+ description: What kind of documentation issue is this?
+ options:
+ - "Error or incorrect information"
+ - "Missing information"
+ - "Unclear or confusing explanation"
+ - "Broken link"
+ - "Typo or grammar"
+ - "Suggestion for improvement"
+ - "Other"
+ validations:
+ required: true
+
+ - type: input
+ id: location
+ attributes:
+ label: Documentation location
+ description: Which documentation page or file is this about?
+ placeholder: "docs/GETTING_STARTED.md, README.md, etc."
+ validations:
+ required: true
+
+ - type: textarea
+ id: current
+ attributes:
+ label: Current documentation
+ description: What does the current documentation say? (copy/paste or describe)
+ placeholder: The current docs say...
+ validations:
+ required: true
+
+ - type: textarea
+ id: issue
+ attributes:
+ label: What's the issue?
+ description: What's wrong or missing?
+ placeholder: The issue is...
+ validations:
+ required: true
+
+ - type: textarea
+ id: suggestion
+ attributes:
+ label: Suggested improvement
+ description: How should it be changed or what should be added?
+ placeholder: It should say... or Add section about...
+ validations:
+ required: true
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional context
+ description: Any other context that might help.
+ placeholder: Any additional information
+
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..a4ec7b3
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,92 @@
+name: Feature Request
+description: Suggest a new feature or enhancement
+title: "[Feature]: "
+labels: ["enhancement"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for suggesting a new feature! Please provide as much detail as possible.
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem statement
+ description: Is your feature request related to a problem? Please describe what you're trying to achieve.
+ placeholder: I'm trying to do X but can't because...
+ validations:
+ required: true
+
+ - type: textarea
+ id: solution
+ attributes:
+ label: Proposed solution
+ description: Describe the solution you'd like to see.
+ placeholder: I would like to be able to...
+ validations:
+ required: true
+
+ - type: textarea
+ id: api
+ attributes:
+ label: Proposed API (if applicable)
+ description: If you have ideas about how the API should look, share them here.
+ placeholder: |
+ ```javascript
+ const config = {
+ newFeature: { ... }
+ };
+ ```
+ render: markdown
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives considered
+ description: Have you tried any workarounds or alternative approaches?
+ placeholder: I tried X but it didn't work because...
+
+ - type: textarea
+ id: use-case
+ attributes:
+ label: Use case
+ description: Describe your use case. How would this feature benefit you and others?
+ placeholder: This would help with...
+ validations:
+ required: true
+
+ - type: dropdown
+ id: scope
+ attributes:
+ label: Which package?
+ description: Which package would this feature be for?
+ options:
+ - "sveltekit-i18n (main lib)"
+ - "@sveltekit-i18n/base"
+ - "@sveltekit-i18n/parser-default"
+ - "@sveltekit-i18n/parser-icu"
+ - "New parser"
+ - "Not sure"
+ validations:
+ required: true
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional context
+ description: Add any other context, screenshots, or examples about the feature request.
+ placeholder: Any additional information
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ description: Please confirm the following
+ options:
+ - label: I have searched existing issues and discussions to avoid duplicates
+ required: true
+ - label: I have checked the [documentation](https://github.com/sveltekit-i18n/lib/tree/master/docs) and [examples](https://github.com/sveltekit-i18n/lib/tree/master/examples)
+ required: true
+ - label: This feature cannot be achieved with current functionality
+ required: true
+
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..91d9f0b
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,43 @@
+## What
+
+
+
+## Why
+
+
+
+Fixes #
+Relates to #
+
+## How
+
+
+
+## Testing
+
+
+
+## Checklist
+
+Before submitting this PR, please ensure:
+
+- [ ] **Tests pass locally** (`npm test`)
+- [ ] **Linter passes** (`npm run lint`)
+- [ ] **Build succeeds** (`npm run build`)
+- [ ] **All commits are atomic** (each commit works independently)
+- [ ] **Commits have clear messages** (imperative mood, descriptive)
+- [ ] **Branch rebased on latest master** (`git rebase origin/master`)
+- [ ] **Documentation updated** (if API or behavior changed)
+- [ ] **Examples updated** (if adding new features)
+
+## Additional Notes
+
+
+
+---
+
+
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..49d6b0f
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,450 @@
+# Contributing to sveltekit-i18n
+
+Thank you for your interest in contributing to `sveltekit-i18n`! We welcome contributions from the community.
+
+> **Note:** We're currently looking for maintainers to help with the project. If you're interested, please see [this issue](https://github.com/sveltekit-i18n/lib/issues/197).
+
+## Table of Contents
+
+- [Ecosystem Overview](#ecosystem-overview)
+- [Repository Structure](#repository-structure)
+- [Getting Started](#getting-started)
+- [Git Workflow](#git-workflow)
+- [Commit Guidelines](#commit-guidelines)
+- [Making Changes](#making-changes)
+- [Testing](#testing)
+- [Pull Request Process](#pull-request-process)
+- [Code Standards](#code-standards)
+- [Release Process](#release-process-maintainers-only)
+- [Getting Help](#getting-help)
+
+## Ecosystem Overview
+
+The `sveltekit-i18n` ecosystem consists of three separate repositories:
+
+- **[sveltekit-i18n/lib](https://github.com/sveltekit-i18n/lib)** (this repository) โ Main user-facing package that combines base with default parser
+- **[@sveltekit-i18n/base](https://github.com/sveltekit-i18n/base)** โ Core i18n functionality with parser support
+- **[@sveltekit-i18n/parsers](https://github.com/sveltekit-i18n/parsers)** โ Message parsers (parser-default, parser-icu)
+
+This repository (`lib`) is what most users install and is the main entry point for contributions.
+
+## Repository Structure
+
+```
+lib/
+โโโ src/ # Source code (TypeScript)
+โ โโโ index.ts # Main entry point
+โ โโโ types.ts # Type definitions
+โโโ tests/ # Test files (Jest)
+โ โโโ specs/ # Test specifications
+โ โโโ data/ # Test data and fixtures
+โโโ examples/ # Working SvelteKit example apps
+โโโ docs/ # User documentation
+โ โโโ INDEX.md
+โ โโโ GETTING_STARTED.md
+โ โโโ ARCHITECTURE.md
+โ โโโ BEST_PRACTICES.md
+โ โโโ TROUBLESHOOTING.md
+โโโ dist/ # Built files (git-ignored)
+โโโ package.json
+```
+
+## Getting Started
+
+### Prerequisites
+
+- Node.js 18+ (or current LTS version)
+- npm or pnpm
+- Git
+
+### Setup
+
+```bash
+# Clone the repository
+git clone https://github.com/sveltekit-i18n/lib.git
+cd lib
+
+# Install dependencies
+npm install
+```
+
+### Development Commands
+
+```bash
+npm run dev # Watch mode with auto-rebuild
+npm run build # Production build
+npm test # Run tests
+npm run lint # Check code style (runs automatically on commit)
+```
+
+## Git Workflow
+
+We use a **rebase-based workflow** to maintain a linear, clean git history.
+
+### Branch Strategy
+
+- `master` โ Stable, production-ready code
+- Use descriptive branch names for your work
+
+### Workflow
+
+```bash
+# Create a feature branch (use any descriptive name)
+git checkout -b my-descriptive-branch-name
+
+# Make changes and commit atomically
+git add .
+git commit -m "Add feature X"
+
+# Keep your branch updated (rebase, NOT merge)
+git fetch origin
+git rebase origin/master
+
+# Push (use force-with-lease after rebase)
+git push origin my-descriptive-branch-name --force-with-lease
+```
+
+### Important Guidelines
+
+- **Use rebase**, not merge commits
+- **Keep linear history** โ no merge commits in the history
+- **Force-push with `--force-with-lease`** (safer than `--force`)
+- Rebase your branch on `master` before creating a PR
+
+## Commit Guidelines
+
+### Atomic Commits
+
+Each commit must be **self-contained and meaningful**:
+
+- โ Works independently (can be cherry-picked)
+- โ Has a single, clear purpose
+- โ Passes tests on its own
+- โ Has a descriptive commit message
+
+### Commit Message Format
+
+```
+Brief description in imperative mood (max 72 characters)
+
+Optional longer explanation if needed. Explain WHAT and WHY,
+not HOW (the code shows how).
+
+Reference related issues if applicable:
+Fixes #123
+Relates to #456
+```
+
+### Good Commit Examples
+
+```
+Add locale switcher component
+Fix translation loading race condition
+Update API docs with TypeScript examples
+Refactor loader matching logic for clarity
+Add tests for route-based translation loading
+```
+
+### Bad Commit Examples
+
+```
+WIP
+fixes
+Update stuff
+Changed some files
+lots of changes
+```
+
+## Making Changes
+
+### Code Changes
+
+- All source code is in `src/`
+- TypeScript strict mode is enforced
+- ESLint runs automatically on commit (pre-commit hook)
+- **No `any` types** โ use proper typing or `unknown` if necessary
+
+### Documentation Changes
+
+- User documentation is in `docs/`
+- All code comments must be in **English**
+- Update relevant documentation when changing APIs
+- Add examples for new features
+
+### Adding Examples
+
+- Examples are in `examples/`
+- Each example should be a complete, working SvelteKit application
+- Include a README explaining the use case and how it works
+
+## Testing
+
+### Running Tests
+
+```bash
+# Run all tests
+npm test
+
+# Watch mode
+npm test -- --watch
+
+# Run specific test file
+npm test -- path/to/test.spec.ts
+```
+
+### Writing Tests
+
+- Place tests in `tests/specs/`
+- Test data and fixtures in `tests/data/`
+- Use Jest with TypeScript
+- Test both functionality and TypeScript types
+- Aim for high coverage on core functionality
+
+### Test Structure
+
+```typescript
+describe('feature name', () => {
+ it('should do something specific', () => {
+ // Arrange - set up test data
+ const input = { locale: 'en', key: 'test' };
+
+ // Act - execute the code
+ const result = someFunction(input);
+
+ // Assert - verify the result
+ expect(result).toBe(expected);
+ });
+});
+```
+
+## Pull Request Process
+
+### Before Creating a PR
+
+1. **Rebase on latest master:** `git rebase origin/master`
+2. **Run tests:** `npm test` (all tests must pass)
+3. **Run linter:** `npm run lint` (no errors)
+4. **Build successfully:** `npm run build`
+5. **Update documentation** if you changed APIs
+
+### PR Title
+
+- Descriptive and concise
+- Use imperative mood: "Add feature" not "Added feature"
+- Examples: "Add locale switching support", "Fix memory leak in loader cache"
+
+### PR Description Template
+
+```markdown
+## What
+Brief description of the changes made.
+
+## Why
+Explanation of why this change is needed. Link to related issues.
+
+## How
+How you implemented it (if the approach is complex or non-obvious).
+
+## Testing
+How you tested the changes. Include test scenarios.
+
+## Checklist
+- [ ] Tests pass locally
+- [ ] Linter passes
+- [ ] Documentation updated (if needed)
+- [ ] All commits are atomic and well-described
+- [ ] Branch rebased on latest master
+```
+
+### Review Process
+
+1. A maintainer will review your PR
+2. Feedback may be requested โ discussion is encouraged
+3. Make requested changes in new commits
+4. Once approved, maintainer will merge using rebase
+
+### Updating Your PR
+
+```bash
+# Make requested changes
+git add .
+git commit -m "Address review feedback"
+
+# Rebase and clean up commits if needed
+git rebase -i origin/master
+
+# Force push with updated commits
+git push origin my-branch-name --force-with-lease
+```
+
+## Code Standards
+
+### TypeScript
+
+- **Strict mode enabled** โ all strict checks enforced
+- **No `any` types** โ use proper types or `unknown` if type is truly unknown
+- **Proper type definitions** for all exports
+- Use `const` assertions where appropriate
+- Leverage TypeScript's inference when possible
+
+### ESLint
+
+- Airbnb TypeScript configuration
+- Auto-fixes run on commit (pre-commit hook)
+- Follow existing code style in the repository
+- Don't disable rules without good reason (and explanation)
+
+### Code Comments
+
+- **English only** โ all comments and documentation in English
+- Use JSDoc for public APIs
+- Explain **WHY**, not WHAT (code shows what)
+- Add comments for non-obvious logic
+
+**Example:**
+
+```typescript
+// โ Good - explains why
+// Use WeakMap to avoid memory leaks when components are destroyed
+const cache = new WeakMap();
+
+// โ Bad - just describes what code does
+// Create a new WeakMap
+const cache = new WeakMap();
+```
+
+## Architecture Overview
+
+For developers working on the codebase, here's a brief technical overview:
+
+### Package Structure
+
+This package extends `@sveltekit-i18n/base` and pre-configures it with `@sveltekit-i18n/parser-default`:
+
+```typescript
+import Base from '@sveltekit-i18n/base';
+import parser from '@sveltekit-i18n/parser-default';
+
+class I18n extends Base {
+ constructor(config) {
+ // Normalize config to include default parser
+ super({
+ ...config,
+ parser: parser(config.parserOptions)
+ });
+ }
+}
+```
+
+### Key Concepts
+
+- **Loaders** โ Define how and when translations load
+- **Routes** โ Match loaders to specific routes
+- **Parser** โ Handles message interpolation
+- **Preprocessing** โ Transforms translation data after loading
+
+### For Detailed Architecture
+
+See the [Architecture Documentation](./docs/ARCHITECTURE.md) for in-depth explanation of how everything works.
+
+## Related Repositories
+
+### Contributing to Other Parts of the Ecosystem
+
+**Core functionality (@sveltekit-i18n/base):**
+- Repository: https://github.com/sveltekit-i18n/base
+- Contribute here for: Core i18n logic, store management, loader system
+
+**Parsers (@sveltekit-i18n/parsers):**
+- Repository: https://github.com/sveltekit-i18n/parsers
+- Contribute here for: Parser syntax changes, new parsers, modifier logic
+
+Each repository has its own issues and contribution guidelines.
+
+## Release Process (Maintainers Only)
+
+This section is for maintainers with publish access.
+
+### Version Bump
+
+```bash
+# Patch release (bug fixes)
+npm version patch
+
+# Minor release (new features, backwards compatible)
+npm version minor
+
+# Major release (breaking changes)
+npm version major
+```
+
+### Publishing
+
+```bash
+# Build the package
+npm run build
+
+# Publish to npm
+npm publish
+
+# Push tags to GitHub
+git push origin master --tags
+```
+
+### Changelog
+
+- Update `CHANGELOG.md` before releasing
+- Follow [Semantic Versioning](https://semver.org/)
+- Group changes by type: Features, Bug Fixes, Breaking Changes
+
+## Getting Help
+
+### Questions
+
+- **GitHub Discussions:** https://github.com/sveltekit-i18n/lib/discussions
+- **Issues:** https://github.com/sveltekit-i18n/lib/issues
+
+### Reporting Bugs
+
+When reporting a bug, include:
+
+- `sveltekit-i18n` version
+- `SvelteKit` version
+- Node.js version
+- Minimal reproduction (CodeSandbox, StackBlitz, or GitHub repo)
+- Expected behavior vs. actual behavior
+- Error messages and stack traces
+
+### Feature Requests
+
+When requesting a feature, include:
+
+- **Use case description** โ What are you trying to achieve?
+- **Proposed API** (if you have ideas)
+- **Why current features don't work** โ Have you tried existing approaches?
+- **Alternatives considered** โ What other solutions did you consider?
+
+### Discussions
+
+For general questions, ideas, or showcasing what you've built, use [GitHub Discussions](https://github.com/sveltekit-i18n/lib/discussions).
+
+## Maintainer Opportunity
+
+We're actively looking for maintainers to help with:
+
+- Reviewing pull requests
+- Triaging issues
+- Maintaining documentation
+- Planning future direction
+
+If you're interested:
+
+1. Review the [maintainer opportunity issue](https://github.com/sveltekit-i18n/lib/issues/197)
+2. Make consistent, quality contributions
+3. Demonstrate understanding of the codebase and architecture
+4. Reach out to express your interest
+
+---
+
+Thank you for contributing to `sveltekit-i18n`! Your efforts help make internationalization easier for the SvelteKit community. ๐
+
diff --git a/README.md b/README.md
index 69c24c1..88c06f6 100644
--- a/README.md
+++ b/README.md
@@ -7,126 +7,232 @@
# sveltekit-i18n
-`sveltekit-i18n` is a tiny library with no external dependencies, built for [Svelte](https://github.com/sveltejs/svelte) and [SvelteKit](https://github.com/sveltejs/kit). It glues [@sveltekit-i18n/base](https://github.com/sveltekit-i18n/base) and [@sveltekit-i18n/parser-default](https://github.com/sveltekit-i18n/parsers/tree/master/parser-default) together to provide you the most straightforward `sveltekit-i18n` solution.
-## Key features
+A lightweight, powerful internationalization (i18n) library designed specifically for [SvelteKit](https://github.com/sveltejs/kit). This package combines [@sveltekit-i18n/base](https://github.com/sveltekit-i18n/base) with [@sveltekit-i18n/parser-default](https://github.com/sveltekit-i18n/parsers/tree/master/parser-default) to provide the quickest way to add multilingual support to your SvelteKit applications.
-โ SvelteKit ready\
-โ SSR support\
-โ Custom data sources โ no matter if you are using local files or remote API to get your translations\
-โ Module-based โ your translations are loaded for visited pages only (and only once!)\
-โ Component-scoped translations โ you can create multiple instances with custom definitions\
-โ Custom modifiers โ you can modify the input data the way you really need\
-โ TS support\
-โ No external dependencies
+## Why sveltekit-i18n?
-## Usage
+- ๐ **SvelteKit-optimized** โ Built specifically for SvelteKit with full SSR support
+- ๐ฆ **Minimal dependencies** โ Only ecosystem packages (base + parser-default)
+- โก **Smart loading** โ Translations load only for visited pages (lazy loading)
+- ๐ฏ **Route-based** โ Automatic translation loading based on your routes
+- ๐ง **Flexible** โ Support for custom data sources (local files, APIs, databases)
+- ๐ **Multiple parsers** โ Choose the syntax that fits your needs
+- ๐ **TypeScript** โ Complete type definitions and typed API
+- ๐จ **Component-scoped** โ Create multiple translation instances for different parts of your app
+
+## Installation
+
+```bash
+npm install sveltekit-i18n
+```
+
+## Quick Start
+
+### 1. Create your translation files
+
+```json
+// src/lib/translations/en/common.json
+{
+ "greeting": "Hello, {{name}}!",
+ "nav.home": "Home",
+ "nav.about": "About"
+}
+```
+
+```json
+// src/lib/translations/cs/common.json
+{
+ "greeting": "Ahoj, {{name}}!",
+ "nav.home": "Domลฏ",
+ "nav.about": "O nรกs"
+}
+```
+
+### 2. Setup i18n configuration
-Setup `translations.js` in your lib folder...
```javascript
+// src/lib/translations/index.js
import i18n from 'sveltekit-i18n';
/** @type {import('sveltekit-i18n').Config} */
-const config = ({
+const config = {
loaders: [
{
locale: 'en',
key: 'common',
- loader: async () => (
- await import('./en/common.json')
- ).default,
- },
- {
- locale: 'en',
- key: 'home',
- routes: ['/'], // you can use regexes as well!
- loader: async () => (
- await import('./en/home.json')
- ).default,
- },
- {
- locale: 'en',
- key: 'about',
- routes: ['/about'],
- loader: async () => (
- await import('./en/about.json')
- ).default,
+ loader: async () => (await import('./en/common.json')).default,
},
{
locale: 'cs',
key: 'common',
- loader: async () => (
- await import('./cs/common.json')
- ).default,
- },
- {
- locale: 'cs',
- key: 'home',
- routes: ['/'],
- loader: async () => (
- await import('./cs/home.json')
- ).default,
- },
- {
- locale: 'cs',
- key: 'about',
- routes: ['/about'],
- loader: async () => (
- await import('./cs/about.json')
- ).default,
+ loader: async () => (await import('./cs/common.json')).default,
},
],
-});
+};
export const { t, locale, locales, loading, loadTranslations } = new i18n(config);
```
-...load your translations in `+layout.js`...
+### 3. Load translations in your layout
```javascript
+// src/routes/+layout.js
import { loadTranslations } from '$lib/translations';
-/** @type {import('@sveltejs/kit').Load} */
+/** @type {import('./$types').LayoutLoad} */
export const load = async ({ url }) => {
const { pathname } = url;
+
+ const initLocale = 'en'; // determine from cookie, user preference, etc.
+
+ await loadTranslations(initLocale, pathname);
+
+ return {};
+};
+```
+
+### 4. Use translations in your components
- const initLocale = 'en'; // get from cookie, user session, ...
+```svelte
+
+
- await loadTranslations(initLocale, pathname); // keep this just before the `return`
+
{$t('common.greeting', { name: 'World' })}
- return {};
-}
+
```
-...and include your translations within pages and components.
+## Key Features
+
+### Route-based Loading
+
+Load translations only for specific routes to optimize performance:
+
+```javascript
+const config = {
+ loaders: [
+ {
+ locale: 'en',
+ key: 'home',
+ routes: ['/'], // Load only on homepage
+ loader: async () => (await import('./en/home.json')).default,
+ },
+ {
+ locale: 'en',
+ key: 'about',
+ routes: ['/about'], // Load only on about page
+ loader: async () => (await import('./en/about.json')).default,
+ },
+ ],
+};
+```
+
+### Placeholders and Modifiers
+
+Use dynamic values in your translations:
+
+```json
+{
+ "welcome": "Welcome, {{name}}!",
+ "items": "You have {{count:number;}} {{count; 1:item; default:items;}}."
+}
+```
```svelte
-
-
-
{$t('common.page', { pageName })}
-
{$t('home.content')}
-
+
{$t('welcome', { name: 'Alice' })}
+
{$t('items', { count: 5 })}
```
-## More info
-[Docs](https://github.com/sveltekit-i18n/lib/tree/master/docs/README.md)\
-[Examples](https://github.com/sveltekit-i18n/lib/tree/master/examples)\
-[Changelog](https://github.com/sveltekit-i18n/lib/releases)
+## Documentation
+
+**๐ [Complete Documentation Index](./docs/INDEX.md)** โ Find everything in one place
+
+### Quick Links
+
+- ๐ [Getting Started Guide](./docs/GETTING_STARTED.md) โ 15-minute tutorial
+- ๐๏ธ [Architecture Overview](./docs/ARCHITECTURE.md) โ How everything works
+- ๐ [API Documentation](./docs/README.md) โ Complete reference
+- โจ [Best Practices](./docs/BEST_PRACTICES.md) โ Production-ready patterns
+- ๐ง [Troubleshooting](./docs/TROUBLESHOOTING.md) โ Common issues & FAQ
+
+## Examples
+
+Explore working examples for different use cases:
+
+- [Multi-page app](./examples/multi-page) โ Most common setup
+- [Locale-based routing](./examples/locale-router) โ SEO-friendly URLs (e.g., `/en/about`)
+- [Component-scoped translations](./examples/component-scoped-ssr) โ Isolated translation contexts
+- [Custom parsers](./examples/parser-icu) โ Using ICU message format
+- [All examples](./examples) โ Complete list of examples
+
+## Advanced Usage
+
+### Need a different parser?
+
+This library uses `@sveltekit-i18n/parser-default`. If you need ICU message format or want to create your own parser, use [@sveltekit-i18n/base](https://github.com/sveltekit-i18n/base) directly:
+
+```javascript
+import i18n from '@sveltekit-i18n/base';
+import parser from '@sveltekit-i18n/parser-icu';
+
+const config = {
+ parser: parser(),
+ // ... rest of config
+};
+```
+
+Learn more about [parsers](https://github.com/sveltekit-i18n/parsers).
+
+## TypeScript Support
+
+Full TypeScript support with complete type definitions for configuration and API:
+
+```typescript
+import i18n, { type Config } from 'sveltekit-i18n';
+
+const config: Config = {
+ loaders: [
+ // ... your loaders
+ ],
+};
+
+export const { t, locale, locales, loading, loadTranslations } = new i18n(config);
+```
+
+**Note:** The library provides type definitions but does not automatically infer translation keys from your JSON files. You can create custom type-safe wrappers if needed (see [Best Practices](./docs/BEST_PRACTICES.md#typescript-patterns)).
+
+## Contributing
+
+We welcome contributions! Please read our [Contributing Guide](./CONTRIBUTING.md) for details on:
+
+- Development setup and workflow
+- Git workflow (rebase-based, linear history)
+- Commit guidelines (atomic commits)
+- Pull request process
+- Code standards and testing
+
+**Note:** We're currently looking for maintainers. If you're interested in helping maintain this project, please reach out via [this issue](https://github.com/sveltekit-i18n/lib/issues/197).
+
+## Changelog
-## Roadmap
+See [Releases](https://github.com/sveltekit-i18n/lib/releases) for version history.
-### Q4 2025
+## Related Packages
-[ ] - Update the examples
-[ ] - Stabalise build & tests
-[ ] - Consolidate issues
+- [@sveltekit-i18n/base](https://github.com/sveltekit-i18n/base) โ Core functionality with custom parser support
+- [@sveltekit-i18n/parser-default](https://github.com/sveltekit-i18n/parsers/tree/master/parser-default) โ Default message parser
+- [@sveltekit-i18n/parser-icu](https://github.com/sveltekit-i18n/parsers/tree/master/parser-icu) โ ICU message format parser
-### Q1 2026
+## License
-[ ] - Storage + State management overhall
\ No newline at end of file
+MIT
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
new file mode 100644
index 0000000..c09f94c
--- /dev/null
+++ b/docs/ARCHITECTURE.md
@@ -0,0 +1,545 @@
+# Architecture Overview
+
+This document explains how `sveltekit-i18n` works internally and how the three packages interact with each other. Understanding the architecture will help you make informed decisions about which package to use and how to configure it for your needs.
+
+## Table of Contents
+
+- [Package Overview](#package-overview)
+- [Package Relationships](#package-relationships)
+- [Data Flow](#data-flow)
+- [Loading Strategy](#loading-strategy)
+- [When to Use Each Package](#when-to-use-each-package)
+- [Core Concepts](#core-concepts)
+
+## Package Overview
+
+The `sveltekit-i18n` ecosystem consists of three main packages:
+
+### 1. @sveltekit-i18n/base
+
+**Role:** Core i18n functionality
+
+**Responsibilities:**
+- Managing translation state (Svelte stores)
+- Loading and caching translations
+- Route matching logic
+- Preprocessing translations
+- Coordinating with parsers
+
+**What it doesn't include:**
+- Message interpolation (delegates to parsers)
+- Default parser
+
+**Use when:** You need custom parsers or maximum flexibility
+
+### 2. sveltekit-i18n (lib)
+
+**Role:** Complete solution with sensible defaults
+
+**Responsibilities:**
+- Everything from `@sveltekit-i18n/base`
+- Pre-configured with `@sveltekit-i18n/parser-default`
+- Simplified API
+
+**Dependencies:** `@sveltekit-i18n/base` + `@sveltekit-i18n/parser-default` (no external dependencies)
+
+**Use when:** You want the quickest setup and are happy with default parser syntax
+
+### 3. @sveltekit-i18n/parsers
+
+**Role:** Message interpolation
+
+**Packages:**
+- `@sveltekit-i18n/parser-default` โ Simple placeholder/modifier syntax
+- `@sveltekit-i18n/parser-icu` โ ICU message format
+
+**Responsibilities:**
+- Interpolating variables into translation strings
+- Formatting (numbers, dates, currencies)
+- Conditional rendering (plurals, gender, etc.)
+
+**Use when:** You need specific message syntax (included automatically with `sveltekit-i18n` or `@sveltekit-i18n/base`)
+
+## Package Relationships
+
+Here's how the packages relate to each other:
+
+```
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ Your SvelteKit App โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
+โ โ
+โ Option 1: Use Complete Solution โ
+โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
+โ โ sveltekit-i18n (lib) โ โ
+โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
+โ โ โ @sveltekit-i18n/base โ โ โ
+โ โ โ (core functionality) โ โ โ
+โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
+โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
+โ โ โ @sveltekit-i18n/parser-default โ โ โ
+โ โ โ (included) โ โ โ
+โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
+โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
+โ โ
+โ Option 2: Use Base with Custom Parser โ
+โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
+โ โ @sveltekit-i18n/base โ โ
+โ โ (you provide the parser) โ โ
+โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
+โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
+โ โ @sveltekit-i18n/parser-icu โ โ
+โ โ or your custom parser โ โ
+โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
+โ โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+```
+
+### Dependency Tree
+
+```
+sveltekit-i18n
+โโโ @sveltekit-i18n/base
+โโโ @sveltekit-i18n/parser-default
+
+@sveltekit-i18n/base
+โโโ (no dependencies)
+
+@sveltekit-i18n/parser-default
+โโโ (no dependencies)
+
+@sveltekit-i18n/parser-icu
+โโโ intl-messageformat
+```
+
+## Data Flow
+
+Here's how translations flow through the system:
+
+### 1. Configuration Phase
+
+```javascript
+import i18n from 'sveltekit-i18n';
+
+const config = {
+ loaders: [
+ {
+ locale: 'en',
+ key: 'common',
+ routes: ['/'],
+ loader: async () => (await import('./en/common.json')).default,
+ },
+ ],
+};
+
+const { t, locale, loadTranslations } = new i18n(config);
+```
+
+**What happens:**
+1. i18n instance is created
+2. Loaders are registered (not executed yet)
+3. Svelte stores are initialized
+4. Parser is configured
+
+### 2. Loading Phase
+
+```javascript
+// In +layout.js
+await loadTranslations('en', '/');
+```
+
+**Flow:**
+
+```
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 1. loadTranslations('en', '/') โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 2. Match loaders โ
+โ - locale === 'en' โ
+โ - routes includes '/' OR routes is undefined โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 3. Execute loader functions โ
+โ loader() โ returns translation data โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 4. Preprocess translations โ
+โ - 'full': flatten to dot notation โ
+โ - 'preserveArrays': flatten but keep arrays โ
+โ - 'none': no changes โ
+โ - custom function: your logic โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 5. Store in translations store โ
+โ { en: { 'common.greeting': 'Hello' } } โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 6. Set locale โ
+โ locale.set('en') โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+```
+
+**Caching:** Each loader runs only once per locale. Results are cached in memory.
+
+### 3. Translation Phase
+
+```svelte
+
{$t('common.greeting', { name: 'Alice' })}
+```
+
+**Flow:**
+
+```
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 1. $t('common.greeting', { name: 'Alice' }) โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 2. Get current locale โ
+โ locale.get() โ 'en' โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 3. Lookup translation โ
+โ translations['en']['common.greeting'] โ
+โ โ 'Hello, {{name}}!' โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 4. Parser.parse() โ
+โ parse('Hello, {{name}}!', [{ name: 'Alice' }]) โ
+โ โ 'Hello, Alice!' โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 5. Return result โ
+โ 'Hello, Alice!' โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+```
+
+### 4. Locale Switch
+
+```javascript
+locale.set('cs');
+```
+
+**Flow:**
+
+```
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 1. locale.set('cs') โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ 2. Check if translations exist โ
+โ translations['cs'] ? โ
+โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ โโโโโโโโโดโโโโโโโโโ
+ โ โ
+ โผ โผ
+ โโโโโโโโโโโ โโโโโโโโโโโโ
+ โ Exists โ โ Missing โ
+ โโโโโโฌโโโโโ โโโโโโฌโโโโโโ
+ โ โ
+ โ โผ
+ โ โโโโโโโโโโโโโโโโโโโโโโโ
+ โ โ Load translations โ
+ โ โ (matching loaders) โ
+ โ โโโโโโฌโโโโโโโโโโโโโโโโโ
+ โ โ
+ โโโโโโโโโโโดโโโโโโโโโ
+ โผ
+ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ 3. Update locale store โ
+ โ triggers reactivity โ
+ โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
+ โ
+ โผ
+ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ 4. All $t() re-evaluate โ
+ โ UI updates โ
+ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+```
+
+## Loading Strategy
+
+### Route-based Loading
+
+The library uses SvelteKit's routing to determine which translations to load:
+
+```javascript
+const config = {
+ loaders: [
+ // No routes specified โ loads on every page
+ {
+ locale: 'en',
+ key: 'common',
+ loader: async () => (await import('./en/common.json')).default,
+ },
+
+ // Exact match โ loads only on '/'
+ {
+ locale: 'en',
+ key: 'home',
+ routes: ['/'],
+ loader: async () => (await import('./en/home.json')).default,
+ },
+
+ // Regex โ loads on matching routes
+ {
+ locale: 'en',
+ key: 'products',
+ routes: [/^\/products/],
+ loader: async () => (await import('./en/products.json')).default,
+ },
+ ],
+};
+```
+
+**Matching algorithm:**
+
+```javascript
+function shouldLoadTranslation(loader, currentRoute) {
+ // No routes specified โ always load
+ if (!loader.routes || loader.routes.length === 0) {
+ return true;
+ }
+
+ // Check each route pattern
+ for (const route of loader.routes) {
+ if (typeof route === 'string') {
+ // Exact string match
+ if (currentRoute === route) return true;
+ } else if (route instanceof RegExp) {
+ // Regex match
+ if (route.test(currentRoute)) return true;
+ }
+ }
+
+ return false;
+}
+```
+
+### Server vs Client Loading
+
+**Server-Side (SSR):**
+- Translations load during `+layout.js` or `+page.js` load
+- Data is serialized and sent to client
+- Hydration picks up from there
+
+**Client-Side:**
+- When locale changes, new translations load on client
+- When navigating, route-specific translations load
+- Loading state available via `$loading` store
+
+### Caching Strategy
+
+**In-Memory Cache:**
+```javascript
+{
+ 'en': {
+ 'common': { /* translations */ },
+ 'home': { /* translations */ },
+ },
+ 'cs': {
+ 'common': { /* translations */ },
+ },
+}
+```
+
+**Cache Refresh:**
+- Client: Never refreshes (single session)
+- Server: Configurable via `cache` option (default: 24 hours)
+
+```javascript
+const config = {
+ cache: 86400000, // 24 hours in milliseconds
+ // or: Number.POSITIVE_INFINITY (never refresh)
+};
+```
+
+## When to Use Each Package
+
+### Use `sveltekit-i18n` (lib)
+
+```javascript
+import i18n from 'sveltekit-i18n';
+```
+
+**When:**
+- โ You want the quickest setup
+- โ Default parser syntax is sufficient
+- โ You don't need custom parsers
+- โ You want zero dependencies
+
+**Best for:** Most projects, rapid prototyping, simple to medium complexity
+
+### Use `@sveltekit-i18n/base`
+
+```javascript
+import i18n from '@sveltekit-i18n/base';
+import parser from '@sveltekit-i18n/parser-icu';
+```
+
+**When:**
+- โ You need ICU message format
+- โ You want to create a custom parser
+- โ You're migrating from another i18n library
+- โ You need specific message syntax
+
+**Best for:** Complex projects, enterprise applications, specific requirements
+
+## Core Concepts
+
+### Svelte Stores
+
+The library uses Svelte stores for reactivity:
+
+```javascript
+// Readable stores (read-only)
+$t // Translation function
+$locales // Available locales
+$loading // Loading state
+$initialized // Initialization state
+
+// Writable stores (can be updated)
+$locale // Current locale
+```
+
+**Reactivity:** When stores update, all components using them re-render automatically.
+
+### Preprocessing
+
+Transforms nested objects into flat dot notation:
+
+**Input:**
+```json
+{
+ "user": {
+ "profile": {
+ "name": "Name",
+ "email": "Email"
+ }
+ }
+}
+```
+
+**Output (preprocess: 'full'):**
+```json
+{
+ "user.profile.name": "Name",
+ "user.profile.email": "Email"
+}
+```
+
+**Why?** Enables efficient lookups and simpler translation keys in code.
+
+### Parser Interface
+
+All parsers implement this interface:
+
+```typescript
+interface Parser {
+ parse(
+ value: any, // Translation value
+ params: any[], // Parameters from $t()
+ locale: string, // Current locale
+ key: string // Translation key
+ ): string;
+}
+```
+
+**Example implementation:**
+
+```javascript
+const simpleParser = () => ({
+ parse: (value, params) => {
+ const vars = params[0] || {};
+ return String(value).replace(
+ /\{(\w+)\}/g,
+ (_, key) => vars[key] ?? key
+ );
+ },
+});
+```
+
+### Namespaces
+
+Namespaces organize translations into logical groups:
+
+```
+common โ Shared UI, navigation, errors
+home โ Homepage content
+products โ Product-related text
+checkout โ Checkout flow
+```
+
+**Benefits:**
+- Easier to manage
+- Enables lazy loading
+- Better code organization
+- Multiple teams can work independently
+
+## Performance Considerations
+
+### Bundle Size
+
+**sveltekit-i18n:**
+- Core: ~5KB (minified)
+- Includes: base + parser-default
+- No external dependencies
+
+**@sveltekit-i18n/base + parser-icu:**
+- Base: ~5KB (zero dependencies)
+- Parser-ICU: ~15KB + intl-messageformat dependency
+
+### Loading Performance
+
+**Best practices:**
+1. Use route-based loading (don't load everything at once)
+2. Keep common translations small
+3. Use code splitting (dynamic imports)
+4. Enable server-side caching
+
+### Runtime Performance
+
+- Translation lookup: O(1) (object property access)
+- Parser execution: Varies by complexity
+- Store updates: Svelte's efficient reactivity
+
+## Summary
+
+The `sveltekit-i18n` architecture is designed to be:
+
+- **Modular** โ Use only what you need
+- **Flexible** โ Customize with parsers and config
+- **Performant** โ Lazy loading and efficient caching
+- **TypeScript** โ Complete type definitions
+- **Developer-friendly** โ Simple API, clear concepts
+
+Choose the right package for your needs and leverage the loading strategies to build efficient, multilingual SvelteKit applications.
+
+## See Also
+
+- [Getting Started](./GETTING_STARTED.md) โ Learn by building
+- [API Documentation](./README.md) โ Complete reference
+- [Best Practices](./BEST_PRACTICES.md) โ Recommended patterns
+- [Parsers](https://github.com/sveltekit-i18n/parsers) โ Parser details
+
diff --git a/docs/BEST_PRACTICES.md b/docs/BEST_PRACTICES.md
new file mode 100644
index 0000000..8c91a4e
--- /dev/null
+++ b/docs/BEST_PRACTICES.md
@@ -0,0 +1,904 @@
+# Best Practices
+
+This guide covers recommended patterns, conventions, and tips for using `sveltekit-i18n` effectively in production applications.
+
+## Table of Contents
+
+- [Translation File Organization](#translation-file-organization)
+- [Key Naming Conventions](#key-naming-conventions)
+- [Performance Optimization](#performance-optimization)
+- [TypeScript Patterns](#typescript-patterns)
+- [SSR and CSR Considerations](#ssr-and-csr-considerations)
+- [Component-Scoped Translations](#component-scoped-translations)
+- [Dynamic Routes and Locales](#dynamic-routes-and-locales)
+- [Content Management](#content-management)
+- [Testing](#testing)
+- [Production Deployment](#production-deployment)
+
+## Translation File Organization
+
+### Directory Structure
+
+Organize translations by locale and namespace:
+
+```
+src/lib/translations/
+โโโ index.js # i18n configuration
+โโโ en/
+โ โโโ common.json # Shared UI, navigation
+โ โโโ home.json # Homepage
+โ โโโ about.json # About page
+โ โโโ products.json # Product pages
+โ โโโ errors.json # Error messages
+โโโ cs/
+โ โโโ common.json
+โ โโโ home.json
+โ โโโ about.json
+โ โโโ products.json
+โ โโโ errors.json
+โโโ de/
+ โโโ common.json
+ โโโ ...
+```
+
+**โ Benefits:**
+- Easy to find translations
+- Clear separation by locale
+- Scalable structure
+
+### Namespace Strategy
+
+#### Common Namespace
+
+Keep frequently used translations in a `common` namespace loaded on every page:
+
+```json
+// common.json
+{
+ "app.name": "My App",
+ "nav.home": "Home",
+ "nav.about": "About",
+ "nav.products": "Products",
+ "button.save": "Save",
+ "button.cancel": "Cancel",
+ "button.delete": "Delete",
+ "error.required": "This field is required",
+ "error.invalid": "Invalid input"
+}
+```
+
+**Keep it small** โ Only essentials that appear across multiple pages.
+
+#### Page-Specific Namespaces
+
+Create separate namespaces for each major page or section:
+
+```javascript
+const config = {
+ loaders: [
+ // Common (all pages)
+ { locale: 'en', key: 'common', loader: async () => (await import('./en/common.json')).default },
+
+ // Page-specific (route-based)
+ { locale: 'en', key: 'home', routes: ['/'], loader: async () => (await import('./en/home.json')).default },
+ { locale: 'en', key: 'about', routes: ['/about'], loader: async () => (await import('./en/about.json')).default },
+ { locale: 'en', key: 'products', routes: [/^\/products/], loader: async () => (await import('./en/products.json')).default },
+ ],
+};
+```
+
+**โ Benefits:**
+- Translations load only when needed
+- Smaller initial bundle
+- Easier to manage
+
+#### Feature-Based Organization
+
+For large apps, organize by feature instead of page:
+
+```
+translations/
+โโโ en/
+โ โโโ common.json
+โ โโโ auth.json # Login, register, password reset
+โ โโโ checkout.json # Cart, payment, confirmation
+โ โโโ profile.json # User profile, settings
+โ โโโ admin.json # Admin panel
+```
+
+```javascript
+const config = {
+ loaders: [
+ { locale: 'en', key: 'auth', routes: ['/login', '/register', '/reset-password'], loader: async () => (await import('./en/auth.json')).default },
+ { locale: 'en', key: 'checkout', routes: [/^\/cart/, /^\/checkout/], loader: async () => (await import('./en/checkout.json')).default },
+ ],
+};
+```
+
+### File Size Guidelines
+
+**Target sizes:**
+- `common.json`: < 5 KB (essential shared content)
+- Page-specific: < 20 KB per file
+- If larger, consider splitting into sub-namespaces
+
+**Example split:**
+
+```
+products/
+โโโ list.json # Product listing page
+โโโ detail.json # Product detail page
+โโโ compare.json # Product comparison
+โโโ reviews.json # Product reviews
+```
+
+## Key Naming Conventions
+
+### Use Dot Notation
+
+Organize keys hierarchically with dots:
+
+```json
+{
+ "user.profile.name": "Name",
+ "user.profile.email": "Email",
+ "user.settings.privacy": "Privacy",
+ "user.settings.notifications": "Notifications"
+}
+```
+
+**โ Clear structure, easy to find related translations**
+
+### Descriptive Names
+
+Use clear, descriptive key names:
+
+```json
+// โ Bad
+{
+ "t1": "Welcome",
+ "btn": "Click",
+ "txt": "Hello"
+}
+
+// โ Good
+{
+ "home.welcome.title": "Welcome",
+ "common.button.submit": "Submit",
+ "greeting.message": "Hello"
+}
+```
+
+### Consistency Patterns
+
+Establish naming patterns and stick to them:
+
+```json
+{
+ // Pages
+ "home.title": "Home",
+ "about.title": "About",
+ "contact.title": "Contact",
+
+ // Forms
+ "form.label.name": "Name",
+ "form.label.email": "Email",
+ "form.placeholder.search": "Search...",
+ "form.error.required": "Required",
+
+ // Buttons
+ "button.submit": "Submit",
+ "button.cancel": "Cancel",
+ "button.save": "Save",
+
+ // Messages
+ "message.success.saved": "Successfully saved",
+ "message.error.failed": "Operation failed"
+}
+```
+
+### Avoid Deep Nesting
+
+**โ Too deep (harder to maintain):**
+
+```json
+{
+ "pages.user.profile.settings.privacy.options.visibility.public": "Public"
+}
+```
+
+**โ Better (balanced):**
+
+```json
+{
+ "profile.privacy.public": "Public"
+}
+```
+
+**Rule of thumb:** Max 3-4 levels deep
+
+### Context in Keys
+
+Include context when the same word has different meanings:
+
+```json
+{
+ "common.button.close": "Close", // Button text
+ "common.adjective.close": "Near", // Adjective
+ "store.status.open": "Open", // Store is open
+ "action.open": "Open file", // Action to open
+ "navigation.home": "Home", // Nav link
+ "address.home": "Home address" // Address type
+}
+```
+
+## Performance Optimization
+
+### Lazy Loading
+
+Load translations only when needed using route-based loaders:
+
+```javascript
+const config = {
+ loaders: [
+ // Always load
+ { locale: 'en', key: 'common', loader: async () => (await import('./en/common.json')).default },
+
+ // Load on specific routes
+ { locale: 'en', key: 'admin', routes: [/^\/admin/], loader: async () => (await import('./en/admin.json')).default },
+ ],
+};
+```
+
+**โ Impact:**
+- Reduces initial bundle size
+- Faster page loads
+- Better performance metrics
+
+### Preload Critical Routes
+
+Preload translations for likely next pages:
+
+```svelte
+
+
+
+```
+
+### Cache Configuration
+
+Set appropriate cache duration for your use case:
+
+```javascript
+// Production: Long cache (good performance)
+const config = {
+ cache: 86400000, // 24 hours
+};
+
+// With CMS: Short cache (content updates frequently)
+const config = {
+ cache: 300000, // 5 minutes
+};
+
+// Static content: Infinite cache
+const config = {
+ cache: Number.POSITIVE_INFINITY,
+};
+```
+
+### Bundle Splitting
+
+Use dynamic imports for large translation files:
+
+```javascript
+// โ Static import (always in bundle)
+import translations from './large-translations.json';
+
+// โ Dynamic import (lazy loaded)
+loader: async () => (await import('./large-translations.json')).default
+```
+
+### Avoid Fallback Locale (If Possible)
+
+`fallbackLocale` doubles translation loading:
+
+```javascript
+// โ Loads both 'cs' and 'en' translations
+const config = {
+ fallbackLocale: 'en',
+};
+
+// โ Complete all translations (no fallback needed)
+// Only loads current locale
+```
+
+Use fallback only during development or partial translations.
+
+## TypeScript Patterns
+
+### Type-Safe Configuration
+
+```typescript
+import i18n, { type Config } from 'sveltekit-i18n';
+
+const config: Config = {
+ loaders: [
+ {
+ locale: 'en',
+ key: 'common',
+ loader: async () => (await import('./en/common.json')).default,
+ },
+ ],
+};
+```
+
+### Translation Key Types (Custom Pattern)
+
+The library doesn't automatically infer types from translation files. If you need type-safe translation keys, you can manually define them:
+
+```typescript
+// translations.d.ts
+export interface TranslationKeys {
+ 'common.greeting': { name: string };
+ 'common.items': { count: number };
+ 'home.title': never; // No params
+}
+
+// translations.ts
+import type { TranslationKeys } from './translations.d';
+
+export const { t } = new i18n(config);
+
+// You'll need to create a typed wrapper for strict checking:
+// export function typedT(
+// key: K,
+// ...params: TranslationKeys[K] extends never ? [] : [TranslationKeys[K]]
+// ): string {
+// return t.get(key, ...(params as any));
+// }
+```
+
+**Note:** This requires manual maintenance. Consider generating types from your translation files using tools like `typesafe-i18n` if you need automatic type inference.
+
+### Typed Helpers
+
+Create typed helper functions:
+
+```typescript
+import { t } from '$lib/translations';
+
+export function formatPrice(amount: number, currency: string = 'USD'): string {
+ return t.get('common.price', { amount }, { currency });
+}
+
+export function pluralize(count: number, singular: string, plural: string): string {
+ return count === 1 ? singular : plural;
+}
+```
+
+### Module Augmentation
+
+Extend types for better IDE support:
+
+```typescript
+// app.d.ts
+declare module '$lib/translations' {
+ export const t: import('svelte/store').Readable<
+ (key: string, vars?: Record, props?: any) => string
+ > & {
+ get: (key: string, vars?: Record, props?: any) => string;
+ };
+
+ export const locale: import('svelte/store').Writable & {
+ get: () => string;
+ };
+
+ // ... other exports
+}
+```
+
+## SSR and CSR Considerations
+
+### Load in Layout
+
+Always load translations in `+layout.js` for SSR:
+
+```javascript
+// src/routes/+layout.js
+import { loadTranslations } from '$lib/translations';
+
+export const load = async ({ url }) => {
+ const { pathname } = url;
+ const initLocale = 'en'; // Determine from cookie, header, etc.
+
+ await loadTranslations(initLocale, pathname);
+
+ return {};
+};
+```
+
+**โ Benefits:**
+- Translations ready on server
+- No flash of untranslated content (FOUC)
+- SEO-friendly
+
+### Handle Loading State
+
+Show proper loading indicators:
+
+```svelte
+
+
+{#if $loading}
+
+```
+
+### 3. Test Loaders Directly
+
+```javascript
+// Test in browser console or separate script
+const loader = async () => (await import('$lib/translations/en/common.json')).default;
+const data = await loader();
+console.log(data);
+```
+
+### 4. Enable Debug Logging
+
+```javascript
+const config = {
+ log: {
+ level: 'debug', // See all operations
+ },
+};
+```
+
+### 5. Check Available Locales
+
+```svelte
+
+
+
Available locales: {$locales.join(', ')}
+```
+
+### 6. Verify Route Matching
+
+```javascript
+// In +layout.js
+export const load = async ({ url }) => {
+ console.log('Current pathname:', url.pathname);
+ await loadTranslations('en', url.pathname);
+ return {};
+};
+```
+
+---
+
+## Frequently Asked Questions
+
+### Can I use this library without SvelteKit?
+
+`sveltekit-i18n` is designed specifically for SvelteKit. For plain Svelte apps, consider:
+- [svelte-i18n](https://github.com/kaisermann/svelte-i18n)
+- [svelte-intl-precompile](https://github.com/cibernox/svelte-intl-precompile)
+
+### Can I use HTML in translations?
+
+No, translations are rendered as text. For HTML content, use `@html`:
+
+```svelte
+
{@html $t('content.with.html')}
+```
+
+**โ ๏ธ Security Warning:** Only use `@html` with trusted content. Never use it with user-generated content.
+
+### How do I handle plurals?
+
+Use the default parser's conditional syntax:
+
+```json
+{
+ "items": "You have {{count}} {{count; 1:item; default:items;}}."
+}
+```
+
+Or use ICU parser for advanced pluralization:
+
+```json
+{
+ "items": "You have {count, plural, =0 {no items} one {# item} other {# items}}."
+}
+```
+
+### Can I change parser after initialization?
+
+Not recommended. Create a new instance instead:
+
+```javascript
+const { t: tDefault } = new i18n(configWithDefaultParser);
+const { t: tICU } = new i18n(configWithICUParser);
+```
+
+### How do I handle right-to-left (RTL) languages?
+
+The library doesn't handle RTL directly. Manage it in your app:
+
+```svelte
+
+
+
+
{$t('content')}
+
+```
+
+### Can I nest translation calls?
+
+No, `$t()` returns a string, not a translation key. Pre-compose your translations:
+
+```javascript
+// โ Won't work
+$t($t('dynamic.key'))
+
+// โ Use variables
+const key = someCondition ? 'key1' : 'key2';
+$t(key)
+```
+
+### How do I translate dynamic content?
+
+Use placeholders:
+
+```json
+{
+ "welcome": "Welcome, {{name}}!",
+ "error": "{{field}} is required."
+}
+```
+
+```javascript
+$t('welcome', { name: userName })
+$t('error', { field: $t('form.field.email') })
+```
+
+### Can I load translations from a database?
+
+Yes! Use async loader:
+
+```javascript
+{
+ locale: 'en',
+ key: 'dynamic',
+ loader: async () => {
+ const res = await fetch('/api/translations/en');
+ return await res.json();
+ },
+}
+```
+
+### How do I handle missing translations during development?
+
+Use `fallbackLocale` temporarily:
+
+```javascript
+const config = {
+ fallbackLocale: 'en', // Fall back to English
+};
+```
+
+Or use a custom `fallbackValue`:
+
+```javascript
+const config = {
+ fallbackValue: '๐ง', // Show construction emoji
+};
+```
+
+### Does this work with SvelteKit adapters?
+
+Yes! Works with all adapters:
+- `@sveltejs/adapter-auto`
+- `@sveltejs/adapter-node`
+- `@sveltejs/adapter-static`
+- `@sveltejs/adapter-vercel`
+- `@sveltejs/adapter-netlify`
+- And others
+
+### How do I translate meta tags (SEO)?
+
+In `+page.js` or `+page.server.js`:
+
+```javascript
+import { t } from '$lib/translations';
+
+export const load = async () => {
+ return {
+ meta: {
+ title: t.get('page.title'),
+ description: t.get('page.description'),
+ },
+ };
+};
+```
+
+In `+page.svelte`:
+
+```svelte
+
+
+
+ {data.meta.title}
+
+
+```
+
+---
+
+## Known Limitations
+
+### 1. Cannot use dots in namespace keys
+
+```javascript
+// โ Won't work correctly
+{ key: 'pages.home' }
+
+// โ Use different separator or remove
+{ key: 'pages_home' }
+{ key: 'home' }
+```
+
+### 2. Translation keys are case-sensitive
+
+```json
+{
+ "Greeting": "Hello"
+}
+```
+
+```javascript
+$t('greeting') // โ Won't find 'Greeting'
+$t('Greeting') // โ Correct
+```
+
+### 3. Locale identifiers must be lowercase
+
+```javascript
+locale.set('EN') // โ Converts to 'en'
+locale.set('en') // โ Correct
+```
+
+### 4. No automatic locale detection
+
+You must explicitly set the locale:
+
+```javascript
+// Detect from browser
+const browserLang = navigator.language.split('-')[0];
+
+// Detect from URL
+const urlLang = url.pathname.split('/')[1];
+
+// Set locale
+await loadTranslations(browserLang, url.pathname);
+```
+
+---
+
+## Getting Help
+
+### Before Asking for Help
+
+1. **Check this guide** โ Most issues are covered here
+2. **Search existing issues** โ Someone might have had the same problem
+3. **Enable debug logging** โ `log: { level: 'debug' }`
+4. **Create a minimal reproduction** โ Isolate the problem
+
+### Where to Get Help
+
+1. **[GitHub Issues](https://github.com/sveltekit-i18n/lib/issues)** โ Bug reports and feature requests
+2. **[GitHub Discussions](https://github.com/sveltekit-i18n/lib/discussions)** โ Questions and community help
+3. **[Examples](../examples)** โ Working code you can reference
+
+### Creating a Good Issue
+
+Include:
+- **SvelteKit version** (`npm list @sveltejs/kit`)
+- **sveltekit-i18n version** (`npm list sveltekit-i18n`)
+- **Minimal reproduction** (CodeSandbox, StackBlitz, or GitHub repo)
+- **Expected behavior** vs **actual behavior**
+- **Error messages** (full stack trace)
+- **Configuration** (anonymized if needed)
+
+**Example:**
+
+```markdown
+## Bug Report
+
+### Environment
+- SvelteKit: 2.0.0
+- sveltekit-i18n: 2.4.2
+- Node: 20.10.0
+
+### Issue
+Translations flash on page load
+
+### Reproduction
+https://stackblitz.com/edit/...
+
+### Expected
+Translations should be ready on initial render
+
+### Actual
+Keys briefly visible before translations load
+
+### Configuration
+... paste your config ...
+```
+
+---
+
+## See Also
+
+- [Getting Started](./GETTING_STARTED.md) โ Setup tutorial
+- [API Documentation](./README.md) โ Complete API reference
+- [Best Practices](./BEST_PRACTICES.md) โ Recommended patterns
+- [Architecture](./ARCHITECTURE.md) โ How it works internally
+- [Examples](../examples) โ Working code examples
+