Skip to content

Commit af27297

Browse files
authored
support Nextjs
2 parents 0fb9899 + e364700 commit af27297

File tree

14 files changed

+433
-187
lines changed

14 files changed

+433
-187
lines changed

.github/workflows/publish.yml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
name: Publish
22

33
on:
4-
push:
5-
branches: [main]
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
68

79
jobs:
810
publish:
@@ -27,15 +29,12 @@ jobs:
2729
restore-keys: |
2830
${{ runner.os }}-node-
2931
30-
- name: Install dependencies
31-
run: npm ci
32-
3332
- name: Build package
3433
run: npm run build
3534
env:
3635
BASE_URL: ${{ secrets.BASE_URL }}
3736

38-
# - name: Publish to NPM
39-
# run: npm publish
40-
# env:
41-
# NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
37+
- name: Publish to NPM
38+
run: npm publish
39+
env:
40+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

README.md

Lines changed: 91 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,34 @@
11
# React AutoLocalise
22

3-
This is SDK for [AutoLocalise](<[AutoLocalise](https://www.autolocalise.com)>).
3+
This is SDK for [AutoLocalise](https://www.autolocalise.com).
44

5-
A lightweight, efficient auto-translation SDK for React, React Native, and Expo applications. This SDK provides seamless integration for automatic content translation and support offline mode.
5+
A lightweight, efficient auto-translation SDK for React and Next.js applications. This SDK provides seamless integration for automatic content translation with support for server-side rendering.
66

77
You don't need to prepare any translation files, just provide your API key and the SDK will handle the rest.
88

99
## Features
1010

11-
- 🌐 Cross-platform support (React Web, React Native, Expo)
11+
- 🌐 React and Next.js support
1212
- 🚀 Automatic string detection and translation
1313
- 🎯 Dynamic parameter interpolation
1414
- 🔍 Static translation tracking
15-
- 🔌 Offline mode support
1615
- ⚙️ Configurable cache TTL
1716
- ⚡️ Tree-shakeable and side-effect free
17+
- 🔄 Server-side rendering support
18+
- 🌍 Automated locale detection via middleware
19+
- ⚡️ Hybrid client/server translation hydration
1820

1921
## Installation
2022

21-
### React Web
22-
2323
```bash
2424
npm install react-autolocalise
2525
# or
2626
yarn add react-autolocalise
2727
```
2828

29-
### React Native
30-
31-
```bash
32-
npm install react-autolocalise @react-native-async-storage/async-storage
33-
# or
34-
yarn add react-autolocalise @react-native-async-storage/async-storage
35-
```
36-
37-
### Expo
38-
39-
```bash
40-
npm install react-autolocalise expo-secure-store
41-
# or
42-
yarn add react-autolocalise expo-secure-store
43-
```
44-
4529
## Usage
4630

47-
### 1. Initialize the SDK
31+
### Initialize the SDK
4832

4933
```typescript
5034
import { TranslationProvider } from "react-autolocalise";
@@ -65,7 +49,7 @@ const App = () => {
6549
};
6650
```
6751

68-
### 2. Use the Translation Hook
52+
### Use the Translation Hook
6953

7054
Basic usage:
7155

@@ -105,71 +89,102 @@ const MyComponent = () => {
10589
};
10690
```
10791

108-
## Locale Format
92+
## Next.js Server-Side Rendering Support
10993

110-
The locale format follows the ISO 639-1 language code standard, optionally combined with an ISO 3166-1 country code:
94+
This SDK provides comprehensive SSR support through middleware-based locale detection and server components. Here's how to implement end-to-end server-side translation:
11195

112-
- Language code only: 'en', 'fr', 'zh', 'ja', etc.
113-
- Language-Region: 'en-US', 'fr-FR', 'zh-CN', 'pt-BR', etc.
96+
### Middleware Setup
11497

115-
## How to get the locale
98+
Create a middleware file to detect user's locale from request headers or URL parameters:
11699

117-
### React
100+
```tsx:/src/middleware.ts
101+
import { NextResponse } from "next/server";
102+
import type { NextRequest } from "next/server";
118103

119-
In React web applications, you can get the user's preferred locale from the browser:
104+
const defaultLocale = "en";
120105

121-
```typescript
122-
// Get the primary locale
123-
const browserLocale = navigator.language; // e.g., 'en-US'
106+
export function middleware(request: NextRequest) {
107+
const { searchParams } = new URL(request.url);
108+
const localeParam = searchParams.get("locale");
124109

125-
// Get all preferred locales
126-
const preferredLocales = navigator.languages; // e.g., ['en-US', 'en']
110+
const acceptLanguage = request.headers.get("accept-language");
111+
const browserLocale = acceptLanguage?.split(',')[0].split(';')[0].substring(0,2);
127112

128-
// Extract just the language code if needed
129-
const languageCode = browserLocale.split("-")[0]; // e.g., 'en'
113+
const locale = localeParam || browserLocale || defaultLocale;
114+
115+
const response = NextResponse.next();
116+
response.headers.set("x-locale", locale);
117+
return response;
118+
}
119+
120+
export const config = {
121+
matcher: "/:path*",
122+
};
130123
```
131124

132-
### React Native
125+
### Server Component Implementation
133126

134-
In React Native, you can get the device locale using the Localization API:
127+
Create server components that utilize the detected locale:
135128

136-
```typescript
137-
import * as Localization from "react-native-localization";
138-
// or
139-
import { NativeModules, Platform } from "react-native";
140-
141-
// Using react-native-localization
142-
const deviceLocale = Localization.locale; // e.g., 'en-US'
143-
144-
// Alternative method using native modules
145-
const deviceLanguage =
146-
Platform.OS === "ios"
147-
? NativeModules.SettingsManager.settings.AppleLocale ||
148-
NativeModules.SettingsManager.settings.AppleLanguages[0]
149-
: NativeModules.I18nManager.localeIdentifier;
129+
```tsx:/src/app/components/ServerComponent.tsx
130+
import { ServerTranslation } from "react-autolocalise/server";
131+
import { headers } from "next/headers";
132+
133+
export default async function ServerComponent() {
134+
const headersList = headers();
135+
const targetLocale = headersList.get("x-locale") || "en";
136+
137+
const serverTranslation = new ServerTranslation({
138+
apiKey: "your-api-key",
139+
sourceLocale: "en",
140+
targetLocale
141+
});
142+
143+
const translations = await serverTranslation.translateTexts([
144+
"Hello from Server Component",
145+
"This component is rendered on the server side"
146+
]);
147+
148+
return (
149+
<div>
150+
<h1>{translations["Hello from Server Component"]}</h1>
151+
<p>{translations["This component is rendered on the server side"]}</p>
152+
</div>
153+
);
154+
}
150155
```
151156

152-
### Expo
157+
### SEO Considerations
153158

154-
In Expo, you can use the Localization API from expo-localization:
159+
While our SDK currently supports server-side rendering of translated content, achieving full locale-specific visibility in search engine results requires additional implementation. We're working on this step by step example and welcome community contributions to:
155160

156-
```typescript
157-
import * as Localization from "expo-localization";
161+
- Implement canonical URL handling for localized content
162+
- Develop locale-specific sitemap generation
163+
- Show hreflang tag implementation
158164

159-
// Get the device locale
160-
const locale = Localization.locale; // e.g., 'en-US'
165+
If you'd like to contribute examples or implementations for these features, please submit a Pull Request!
161166

162-
// Get just the language code
163-
const languageCode = locale.split("-")[0]; // e.g., 'en'
167+
## Locale Format
164168

165-
// Get the user's preferred locales
166-
const preferredLocales = Localization.locales; // e.g., ['en-US', 'en']
169+
The locale format follows the ISO 639-1 language code standard, optionally combined with an ISO 3166-1 country code:
167170

168-
// Check if the device uses RTL layout
169-
const isRTL = Localization.isRTL;
170-
```
171+
- Language code only: 'en', 'fr', 'zh', 'ja', etc.
172+
- Language-Region: 'en-US', 'fr-FR', 'zh-CN', 'pt-BR', etc.
171173

172-
Note: When running Expo in a web browser, it will use the browser's locale settings (navigator.language) automatically.
174+
## How to get the locale
175+
176+
In React web applications, you can get the user's preferred locale from the browser:
177+
178+
```typescript
179+
// Get the primary locale
180+
const browserLocale = navigator.language; // e.g., 'en-US'
181+
182+
// Get all preferred locales
183+
const preferredLocales = navigator.languages; // e.g., ['en-US', 'en']
184+
185+
// Extract just the language code if needed
186+
const languageCode = browserLocale.split("-")[0]; // e.g., 'en'
187+
```
173188

174189
## API Reference
175190

@@ -181,12 +196,14 @@ Note: When running Expo in a web browser, it will use the browser's locale setti
181196

182197
### TranslationConfig
183198

184-
| Property | Type | Required | Description |
185-
| ------------ | ------ | -------- | ------------------------------------------------------------ |
186-
| apiKey | string | Yes | Your API key for the translation service |
187-
| sourceLocale | string | No | Source locale for translations (will auto-detect if omitted) |
188-
| targetLocale | string | Yes | Target locale for translations |
189-
| cacheTTL | number | No | Cache validity period in hours (default: 24) |
199+
| Property | Type | Required | Description |
200+
| ------------ | ------ | -------- | -------------------------------------------- |
201+
| apiKey | string | Yes | Your API key for the translation service |
202+
| sourceLocale | string | Yes | Source locale for translations |
203+
| targetLocale | string | Yes | Target locale for translations |
204+
| cacheTTL | number | No | Cache validity period in hours (default: 24) |
205+
206+
**Tips**: When `sourceLocale` === `targetLocale` no translation requests will be send.
190207

191208
### useAutoTranslate Hook
192209

jest.config.cjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ module.exports = {
33
testEnvironment: "jsdom",
44
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
55
transform: {
6-
"^.+\\.(ts|tsx)$": "ts-jest",
6+
"^.+\\.(ts|tsx)$": [
7+
"ts-jest",
8+
{
9+
tsconfig: "tsconfig.json",
10+
},
11+
],
712
},
813
setupFilesAfterEnv: ["@testing-library/jest-dom"],
914
testMatch: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[tj]s?(x)"],

package-lock.json

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

0 commit comments

Comments
 (0)