Skip to content

Commit 94ef861

Browse files
committed
docs: update README with installation steps and usage instructions; enhance test setup for translations
feat: update useLocalizer to load translations from window.localizer for immediate access; bump version to 0.0.5
1 parent 70ed49b commit 94ef861

File tree

6 files changed

+138
-23
lines changed

6 files changed

+138
-23
lines changed

README.md

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,41 @@ yarn add @devwizard/laravel-localizer-react
2727

2828
```bash
2929
composer require devwizardhq/laravel-localizer
30-
php artisan localizer:install --framework=react
30+
php artisan localizer:install
3131
```
3232

33+
The install command will:
34+
- ✅ Publish configuration files
35+
- ✅ Create default locale files
36+
- ✅ Install npm package (optional)
37+
- ✅ Generate initial TypeScript files
38+
39+
**Note:** You'll need to manually add the bootstrap setup (see step 1 below).
40+
3341
## Setup
3442

35-
### 1. Add Vite Plugin
43+
### 1. Initialize Translations in Bootstrap
44+
45+
Add this to your `resources/js/bootstrap.ts`:
46+
47+
```typescript
48+
import { translations } from '@/lang';
49+
50+
declare global {
51+
interface Window {
52+
localizer: {
53+
translations: Record<string, Record<string, string>>;
54+
};
55+
}
56+
}
57+
58+
// Auto-initialize Laravel Localizer translations
59+
window.localizer = {
60+
translations: translations,
61+
};
62+
```
63+
64+
### 2. Add Vite Plugin
3665

3766
Update your `vite.config.ts`:
3867

@@ -51,14 +80,76 @@ export default defineConfig({
5180
});
5281
```
5382

54-
### 2. Generate Translation Files
83+
### 2. Add Vite Plugin
84+
85+
Update your `vite.config.ts`:
86+
87+
```typescript
88+
import { defineConfig } from 'vite';
89+
import react from '@vitejs/plugin-react';
90+
import { laravelLocalizer } from '@devwizard/laravel-localizer-react/vite';
91+
92+
export default defineConfig({
93+
plugins: [
94+
react(),
95+
laravelLocalizer({
96+
debug: true, // Enable debug logging (optional)
97+
}),
98+
],
99+
});
100+
```
101+
102+
### 3. Generate Translation Files
55103

56104
```bash
57105
php artisan localizer:generate --all
58106
```
59107

60108
This creates TypeScript files in `resources/js/lang/` directory.
61109

110+
## How It Works
111+
112+
The Laravel Localizer uses a simple and efficient approach:
113+
114+
1. **Generate** - PHP generates TypeScript files from Laravel language files
115+
2. **Load** - Translations are loaded once at app startup via `window.localizer`
116+
3. **Access** - React components access translations synchronously via `useLocalizer` hook
117+
118+
```
119+
┌─────────────────┐
120+
│ Laravel Lang │ lang/en.json, lang/en/*.php
121+
│ Files │
122+
└────────┬────────┘
123+
124+
│ php artisan localizer:generate
125+
126+
┌─────────────────┐
127+
│ TypeScript │ resources/js/lang/en.ts
128+
│ Files │ resources/js/lang/index.ts
129+
└────────┬────────┘
130+
131+
│ import { translations } from '@/lang'
132+
133+
┌─────────────────┐
134+
│ window.localizer│ { translations: { en: {...}, bn: {...} } }
135+
│ │
136+
└────────┬────────┘
137+
138+
│ useLocalizer() hook
139+
140+
┌─────────────────┐
141+
│ React Components│ {__('welcome')}
142+
└─────────────────┘
143+
```
144+
145+
### Why `window.localizer`?
146+
147+
-**Synchronous Access** - No async loading delays
148+
-**All Locales Ready** - All translations available immediately
149+
-**Build-time Optimization** - Vite can tree-shake unused translations
150+
-**Test-friendly** - Works in Jest/Vitest without mocking
151+
-**No Re-renders** - No useEffect or async state updates
152+
62153
## Usage
63154

64155
### Basic Usage

__tests__/setup.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,29 @@ jest.mock('@inertiajs/react', () => ({
55
usePage: jest.fn(),
66
}));
77

8+
// Setup window.localizer for tests
9+
beforeAll(() => {
10+
(window as any).localizer = {
11+
translations: {
12+
en: {
13+
welcome: 'Welcome',
14+
'validation.required': 'This field is required',
15+
'greeting.hello': 'Hello :name!',
16+
'items.count': 'You have :count items',
17+
'user.items': ':name has :count items',
18+
},
19+
ar: {
20+
welcome: 'مرحبا',
21+
'validation.required': 'هذا الحقل مطلوب',
22+
},
23+
bn: {
24+
welcome: 'স্বাগতম',
25+
'validation.required': 'এই ক্ষেত্রটি প্রয়োজনীয়',
26+
},
27+
},
28+
};
29+
});
30+
831
// Suppress console errors during tests unless explicitly needed
932
const originalError = console.error;
1033
beforeAll(() => {

__tests__/useLocalizer.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ describe('useLocalizer', () => {
229229
'validation.required': 'This field is required',
230230
'greeting.hello': 'Hello :name!',
231231
'items.count': 'You have :count items',
232+
'user.items': ':name has :count items',
232233
});
233234
});
234235
});

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devwizard/laravel-localizer-react",
3-
"version": "0.0.4",
3+
"version": "0.0.5",
44
"type": "module",
55
"description": "React integration for Laravel Localizer with Vite plugin, useLocalizer hook, and automatic TypeScript generation",
66
"main": "dist/index.js",

src/useLocalizer.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -190,32 +190,32 @@ export function useLocalizer(options: UseLocalizerOptions = {}): UseLocalizerRet
190190

191191
const availableLocales = useMemo(() => props.locale?.available || {}, [props.locale?.available]);
192192

193-
// Dynamically import translations from generated files
194-
// Note: By default, translations are loaded from '@/lang' folder (resources/js/lang)
195-
// Users can customize this path by passing langPath option
196-
// The actual translations object will be available at runtime
193+
// Load translations from window object (initialized in bootstrap.ts)
194+
// The langPath option is used by the vite plugin to know where to watch for changes
195+
// and where the generated files should be located
197196
const translations = useMemo<Record<string, string>>(() => {
198197
try {
199-
// This will be resolved at build time by Vite
200-
// The generated files are created by php artisan localizer:generate
201-
interface WindowWithTranslations extends Window {
202-
__LARAVEL_LOCALIZER_TRANSLATIONS__?: Record<string, Record<string, string>>;
198+
// Translations are automatically loaded in bootstrap.ts from the generated files
199+
// This provides immediate, synchronous access to all translations
200+
interface WindowWithLocalizer extends Window {
201+
localizer?: {
202+
translations: Record<string, Record<string, string>>;
203+
};
203204
}
204-
const translations =
205-
(window as WindowWithTranslations).__LARAVEL_LOCALIZER_TRANSLATIONS__?.[locale] || {};
205+
const localizer = (window as WindowWithLocalizer).localizer;
206206

207-
// Note: langPath is stored for future use if needed for dynamic imports
208-
// Currently, translations are loaded globally via window object
209-
if (Object.keys(translations).length === 0 && langPath !== '@/lang') {
207+
if (!localizer?.translations) {
210208
console.warn(
211-
`[Laravel Localizer] Custom langPath '${langPath}' specified but translations not found. Ensure your vite.config has proper path alias.`
209+
`[Laravel Localizer] Translations not initialized. Make sure bootstrap.ts imports from '${langPath}'.`
212210
);
211+
return {};
213212
}
214213

215-
return translations;
216-
} catch {
214+
return localizer.translations[locale] || {};
215+
} catch (error) {
217216
console.warn(
218-
`[Laravel Localizer] Could not load translations for locale: ${locale}. Default path is '${langPath}'.`
217+
`[Laravel Localizer] Could not load translations for locale: ${locale}`,
218+
error
219219
);
220220
return {};
221221
}

0 commit comments

Comments
 (0)