Skip to content

Commit e364700

Browse files
committed
update server side rendering support
1 parent 45c6e41 commit e364700

File tree

8 files changed

+241
-146
lines changed

8 files changed

+241
-146
lines changed

README.md

Lines changed: 79 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,63 +6,6 @@ A lightweight, efficient auto-translation SDK for React and Next.js applications
66

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

9-
## Next.js Server-Side Rendering Support
10-
11-
This SDK fully supports Next.js server-side rendering (SSR). You can pre-fetch translations on the server and hydrate the client with these translations for a seamless user experience.
12-
13-
### Usage with Next.js
14-
15-
```tsx
16-
// pages/index.tsx
17-
import { GetServerSideProps } from "next";
18-
import {
19-
TranslationProvider,
20-
useAutoTranslate,
21-
getServerSideTranslations,
22-
} from "react-autolocalise";
23-
24-
// Your component using translations
25-
function MyComponent() {
26-
const { translate } = useAutoTranslate();
27-
return <h1>{translate("Hello World")}</h1>;
28-
}
29-
30-
// Page component
31-
function HomePage({ translations }) {
32-
return (
33-
<TranslationProvider
34-
config={{
35-
apiKey: "your-api-key",
36-
sourceLocale: "en",
37-
targetLocale: "fr",
38-
}}
39-
initialTranslations={translations}
40-
>
41-
<MyComponent />
42-
</TranslationProvider>
43-
);
44-
}
45-
46-
// Server-side props
47-
export const getServerSideProps: GetServerSideProps = async () => {
48-
const translations = await getServerSideTranslations({
49-
apiKey: "your-api-key",
50-
sourceLocale: "en",
51-
targetLocale: "fr",
52-
});
53-
54-
return {
55-
props: {
56-
translations,
57-
},
58-
};
59-
};
60-
61-
export default HomePage;
62-
```
63-
64-
See the `examples/nextjs-usage.tsx` file for a more detailed example.
65-
669
## Features
6710

6811
- 🌐 React and Next.js support
@@ -72,6 +15,8 @@ See the `examples/nextjs-usage.tsx` file for a more detailed example.
7215
- ⚙️ Configurable cache TTL
7316
- ⚡️ Tree-shakeable and side-effect free
7417
- 🔄 Server-side rendering support
18+
- 🌍 Automated locale detection via middleware
19+
- ⚡️ Hybrid client/server translation hydration
7520

7621
## Installation
7722

@@ -83,7 +28,7 @@ yarn add react-autolocalise
8328

8429
## Usage
8530

86-
### 1. Initialize the SDK
31+
### Initialize the SDK
8732

8833
```typescript
8934
import { TranslationProvider } from "react-autolocalise";
@@ -104,7 +49,7 @@ const App = () => {
10449
};
10550
```
10651

107-
### 2. Use the Translation Hook
52+
### Use the Translation Hook
10853

10954
Basic usage:
11055

@@ -144,6 +89,81 @@ const MyComponent = () => {
14489
};
14590
```
14691

92+
## Next.js Server-Side Rendering Support
93+
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:
95+
96+
### Middleware Setup
97+
98+
Create a middleware file to detect user's locale from request headers or URL parameters:
99+
100+
```tsx:/src/middleware.ts
101+
import { NextResponse } from "next/server";
102+
import type { NextRequest } from "next/server";
103+
104+
const defaultLocale = "en";
105+
106+
export function middleware(request: NextRequest) {
107+
const { searchParams } = new URL(request.url);
108+
const localeParam = searchParams.get("locale");
109+
110+
const acceptLanguage = request.headers.get("accept-language");
111+
const browserLocale = acceptLanguage?.split(',')[0].split(';')[0].substring(0,2);
112+
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+
};
123+
```
124+
125+
### Server Component Implementation
126+
127+
Create server components that utilize the detected locale:
128+
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+
}
155+
```
156+
157+
### SEO Considerations
158+
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:
160+
161+
- Implement canonical URL handling for localized content
162+
- Develop locale-specific sitemap generation
163+
- Show hreflang tag implementation
164+
165+
If you'd like to contribute examples or implementations for these features, please submit a Pull Request!
166+
147167
## Locale Format
148168

149169
The locale format follows the ISO 639-1 language code standard, optionally combined with an ISO 3166-1 country code:

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
"import": "./dist/index.mjs",
1212
"require": "./dist/index.cjs",
1313
"types": "./dist/index.d.ts"
14+
},
15+
"./server": {
16+
"import": "./dist/server/index.mjs",
17+
"require": "./dist/server/index.cjs",
18+
"types": "./dist/server/index.d.ts"
1419
}
1520
},
1621
"sideEffects": false,

rollup.config.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
import typescript from "@rollup/plugin-typescript";
22

3-
export default {
3+
// Configuration shared between both builds
4+
const commonConfig = {
5+
external: [
6+
"react",
7+
"react-dom",
8+
"react-native",
9+
"@react-native-async-storage/async-storage",
10+
"next",
11+
],
12+
plugins: [
13+
typescript({
14+
tsconfig: "./tsconfig.json",
15+
declaration: true,
16+
declarationDir: "dist",
17+
}),
18+
],
19+
};
20+
21+
// Main module build configuration
22+
const mainConfig = {
23+
...commonConfig,
424
input: "src/index.ts",
525
output: [
626
{
@@ -16,18 +36,26 @@ export default {
1636
exports: "named",
1737
},
1838
],
19-
external: [
20-
"react",
21-
"react-dom",
22-
"react-native",
23-
"@react-native-async-storage/async-storage",
24-
"next",
25-
],
26-
plugins: [
27-
typescript({
28-
tsconfig: "./tsconfig.json",
29-
declaration: true,
30-
declarationDir: "dist",
31-
}),
39+
};
40+
41+
// Server module build configuration
42+
const serverConfig = {
43+
...commonConfig,
44+
input: "src/server/index.ts",
45+
output: [
46+
{
47+
file: "dist/server/index.cjs",
48+
format: "cjs",
49+
sourcemap: true,
50+
exports: "named",
51+
},
52+
{
53+
file: "dist/server/index.mjs",
54+
format: "es",
55+
sourcemap: true,
56+
exports: "named",
57+
},
3258
],
3359
};
60+
61+
export default [mainConfig, serverConfig];

src/context/TranslationContext.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ export const TranslationProvider: React.FC<TranslationProviderSSRProps> = ({
7272
try {
7373
// If we have initial translations, we can skip the initial fetch
7474
if (!initialTranslations) {
75-
await service.init();
75+
if (config.sourceLocale !== config.targetLocale) {
76+
await service.init();
77+
}
7678
} else {
7779
// Mark as initialized even with preloaded translations
7880
service.isInitialized = true;

src/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
export {
22
TranslationProvider,
33
useAutoTranslate,
4+
TranslationProviderSSRProps,
45
} from "./context/TranslationContext";
56

6-
// Next.js specific exports
7-
export { getServerSideTranslations } from "./nextjs";
8-
97
// Export isServer utility
108
export { isServer } from "./storage";
119

src/nextjs.ts

Lines changed: 0 additions & 69 deletions
This file was deleted.

0 commit comments

Comments
 (0)