Skip to content

Commit

Permalink
debug
Browse files Browse the repository at this point in the history
  • Loading branch information
KishiTheMechanic committed Oct 26, 2024
1 parent 78c2ae2 commit 2a2ce4a
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 55 deletions.
94 changes: 48 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,18 @@ preferred locale based on the URL.

```typescript
import { App, fsRoutes, staticFiles, trailingSlashes } from 'fresh'
import { i18nPlugin, type TranslationState } from '@elsoul/fresh-i18n'
import { i18nPlugin } from 'fresh-i18n'
import type { ExtendedState } from '@/utils/state.ts'

export const app = new App<{ state: TranslationState }>({
export const app = new App<ExtendedState>({
root: import.meta.url,
})
.use(staticFiles())
.use(trailingSlashes('never'))
.use(i18nPlugin({
languages: ['en', 'ja'], // Supported languages
defaultLanguage: 'en', // Default language
localesDir: './locales', // Path to locale JSON files
languages: ['en', 'ja'],
defaultLanguage: 'en',
localesDir: './locales',
}))

await fsRoutes(app, {
Expand All @@ -66,6 +67,43 @@ if (import.meta.main) {
}
```

#### Define an Extended State with TranslationState

If you are managing additional global state in your Fresh app, such as metadata
or theme settings, you can extend TranslationState to include your own
properties. This extended state can then be used across your app, with
translation data (t) accessible directly in request handlers, enabling
Server-Side Rendering (SSR) with fully localized content.

##### Example

In the following example, TranslationState from @elsoul/fresh-i18n is combined
with a custom State interface to create ExtendedState. This ExtendedState
includes both translation data and other application-specific properties, making
it convenient for global state management.

ExtendedState can then be used in request handlers to access translation data
directly via ctx.state.t, enabling SSR with localized data.

```typescript
import { createDefine } from 'fresh'
import type { TranslationState } from '@elsoul/fresh-i18n'

interface State {
title?: string
theme?: string
description?: string
ogImage?: string
noIndex?: boolean
}

// Combine TranslationState with custom State properties
export type ExtendedState = State & TranslationState

// Define the extended state for use in your Fresh app
export const define = createDefine<ExtendedState>()
```

### Step 2: Create Locale JSON Files

Inside the `locales` directory, create subfolders for each locale and organize
Expand Down Expand Up @@ -109,13 +147,13 @@ translations and handle language switching dynamically.
import { useLocale, useTranslation } from '@elsoul/fresh-i18n'

export default function IslandsComponent() {
const { t } = useTranslation('common') // Uses "common" namespace
const { t } = useTranslation()
const { locale, changeLanguage } = useLocale()

return (
<div>
<h1>{t('title')}</h1> {/* Outputs "Home" or "ホーム" */}
<p>{t('welcome')}</p> {/* Outputs "Welcome" or "ようこそ" */}
<h1>{t('common.title')}</h1> {/* Outputs "Home" or "ホーム" */}
<p>{t('common.welcome')}</p> {/* Outputs "Welcome" or "ようこそ" */}
<p>Current language: {locale}</p>
<button onClick={() => changeLanguage('en')}>English</button>
<button onClick={() => changeLanguage('ja')}>日本語</button>
Expand All @@ -124,44 +162,8 @@ export default function IslandsComponent() {
}
```

### Define an Extended State with TranslationState

If you are managing additional global state in your Fresh app, such as metadata
or theme settings, you can extend TranslationState to include your own
properties. This extended state can then be used across your app, with
translation data (t) accessible directly in request handlers, enabling
Server-Side Rendering (SSR) with fully localized content.

#### Example

In the following example, TranslationState from @elsoul/fresh-i18n is combined
with a custom State interface to create ExtendedState. This ExtendedState
includes both translation data and other application-specific properties, making
it convenient for global state management.

ExtendedState can then be used in request handlers to access translation data
directly via ctx.state.t, enabling SSR with localized data.

```typescript
import { createDefine } from 'fresh'
import type { TranslationState } from '@elsoul/fresh-i18n'

interface State {
title?: string
lang?: string
theme?: string
description?: string
ogImage?: string
noIndex?: boolean
}

// Combine TranslationState with custom State properties
export type ExtendedState = State & TranslationState

// Define the extended state for use in your Fresh app
export const define = createDefine<ExtendedState>()

// Example usage in a route handler
```tsx
// Example usage in a route handler for SSR
export const handler = define.handlers({
GET(ctx) {
console.log('ctx', ctx.state.t) // Access translation data directly
Expand Down
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@elsoul/fresh-i18n",
"version": "0.9.6",
"version": "0.9.7",
"description": "A simple and flexible internationalization (i18n) plugin for Deno's Fresh framework.",
"runtimes": ["deno", "browser"],
"exports": "./mod.ts",
Expand Down
2 changes: 1 addition & 1 deletion src/i18nPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const i18nPlugin = (
: url.pathname

ctx.state.path = rootPath
ctx.state.lang = lang
ctx.state.locale = lang

pathname.value = rootPath

Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@ export type MiddlewareFn<State> = (
export interface TranslationState {
t: Record<string, Record<string, string>>
path: string
lang: string
locale: string
}
14 changes: 8 additions & 6 deletions src/useTranslation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@ import { translationData } from '@/src/store.ts'
*/
export function useTranslation(): { t: (key: string) => string } {
const translate = (key: string): string => {
const keys = key.split('.')
let value: unknown = translationData.value
const keys = key.split('.') // Split the key by dot
let value: unknown = translationData.value // Get the value from translationData

console.log('Translation Data:', translationData.value) // Check translation data

for (const k of keys) {
if (value && typeof value === 'object' && k in value) {
value = (value as Record<string, unknown>)[k]
value = (value as Record<string, unknown>)[k] // Retrieve the nested key
} else {
return key // Fallback to the key if the path is not found
return key // Return the key if not found
}
}

return typeof value === 'string' ? value : key
return typeof value === 'string' ? value : key // Return value if it's a string, otherwise return the key
}

return { t: translate }
return { t: translate } // Return the translation function
}

0 comments on commit 2a2ce4a

Please sign in to comment.