Skip to content

Commit 9147e61

Browse files
committed
option to generate default language page
Currently, the plugin does not generate dedicated page for default language. However, dedicated page for default language is useful for below cases: 1. We want to specify language when sharing a link 2. Server-side redirect using Accept-language header.
1 parent 3ff0d29 commit 9147e61

File tree

7 files changed

+40
-16
lines changed

7 files changed

+40
-16
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,15 +243,16 @@ const Header = ({siteTitle}) => {
243243

244244
## Plugin Options
245245

246-
| Option | Type | Description |
247-
| --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
248-
| path | string | path to the folder with JSON translations |
249-
| languages | string[] | supported language keys |
250-
| defaultLanguage | string | default language when visiting `/page` instead of `/es/page` |
251-
| redirect | boolean | if the value is `true`, `/` or `/page-2` will be redirected to the user's preferred language router. e.g) `/es` or `/es/page-2`. Otherwise, the pages will render `defaultLangugage` language. Default is `true` |
252-
| siteUrl | string | public site url, is used to generate language specific meta tags |
253-
| pages | array | an array of [page options](#page-options) used to modify plugin behaviour for specific pages |
254-
| i18nextOptions | object | [i18next configuration options](https://www.i18next.com/overview/configuration-options) |
246+
| Option | Type | Description |
247+
| --------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
248+
| path | string | path to the folder with JSON translations |
249+
| languages | string[] | supported language keys |
250+
| defaultLanguage | string | default language when visiting `/page` instead of `/es/page` |
251+
| generateDefaultLanguagePage | string | generate dedicated page for default language. e.g) `/en/page`. It is useful when you need page urls for all languages. For example, server-side [redirect](https://www.gatsbyjs.com/docs/reference/config-files/actions/#createRedirect) using `Accept-Language` header. Default is `false`. |
252+
| redirect | boolean | if the value is `true`, `/` or `/page-2` will be redirected to the user's preferred language router. e.g) `/es` or `/es/page-2`. Otherwise, the pages will render `defaultLangugage` language. Default is `true` |
253+
| siteUrl | string | public site url, is used to generate language specific meta tags |
254+
| pages | array | an array of [page options](#page-options) used to modify plugin behaviour for specific pages |
255+
| i18nextOptions | object | [i18next configuration options](https://www.i18next.com/overview/configuration-options) |
255256

256257
## Page options
257258

src/Link.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ type Props = GatsbyLinkProps<any> & {language?: string};
88
export const Link: React.FC<Props> = ({language, to, onClick, ...rest}) => {
99
const context = useContext(I18nextContext);
1010
const urlLanguage = language || context.language;
11-
const link = urlLanguage !== context.defaultLanguage ? `/${urlLanguage}${to}` : to;
11+
const link = context.routed
12+
? `/${urlLanguage}${to}`
13+
: urlLanguage !== context.defaultLanguage
14+
? `/${urlLanguage}${to}`
15+
: to;
1216

1317
return (
1418
// @ts-ignore

src/i18nextContext.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const I18nextContext = React.createContext<I18NextContext>({
66
languages: ['en'],
77
routed: false,
88
defaultLanguage: 'en',
9+
generateDefaultLanguagePage: false,
910
originalPath: '/',
1011
path: '/'
1112
});

src/plugin/onCreatePage.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ export const onCreatePage = async (
3333
}
3434

3535
const {createPage, deletePage} = actions;
36-
const {defaultLanguage = 'en', languages = ['en'], pages = []} = pluginOptions;
36+
const {
37+
defaultLanguage = 'en',
38+
generateDefaultLanguagePage = false,
39+
languages = ['en'],
40+
pages = []
41+
} = pluginOptions;
3742

3843
type GeneratePageParams = {
3944
language: string;
@@ -60,6 +65,7 @@ export const onCreatePage = async (
6065
language,
6166
languages: pageOptions?.languages || languages,
6267
defaultLanguage,
68+
generateDefaultLanguagePage,
6369
routed,
6470
resources,
6571
originalPath,
@@ -72,7 +78,9 @@ export const onCreatePage = async (
7278
const pageOptions = pages.find((opt) => match(opt.matchPath)(page.path));
7379

7480
let newPage;
75-
let alternativeLanguages = languages.filter((lng) => lng !== defaultLanguage);
81+
let alternativeLanguages = generateDefaultLanguagePage
82+
? languages
83+
: languages.filter((lng) => lng !== defaultLanguage);
7684

7785
if (pageOptions?.excludeLanguages) {
7886
alternativeLanguages = alternativeLanguages.filter(
@@ -81,7 +89,9 @@ export const onCreatePage = async (
8189
}
8290

8391
if (pageOptions?.languages) {
84-
alternativeLanguages = pageOptions.languages.filter((lng) => lng !== defaultLanguage);
92+
alternativeLanguages = generateDefaultLanguagePage
93+
? pageOptions.languages
94+
: pageOptions.languages.filter((lng) => lng !== defaultLanguage);
8595
}
8696

8797
if (pageOptions?.getLanguageFromPath) {

src/plugin/wrapPageElement.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ const withI18next = (i18n: I18n, context: I18NextContext) => (children: any) =>
1919

2020
export const wrapPageElement = (
2121
{element, props}: WrapPageElementBrowserArgs<any, PageContext>,
22-
{i18nextOptions = {}, redirect = true, siteUrl}: PluginOptions
22+
{
23+
i18nextOptions = {},
24+
redirect = true,
25+
generateDefaultLanguagePage = false,
26+
siteUrl
27+
}: PluginOptions
2328
) => {
2429
if (!props) return;
2530
const {pageContext, location} = props;
@@ -89,6 +94,7 @@ export const wrapPageElement = (
8994
languages,
9095
originalPath,
9196
defaultLanguage,
97+
generateDefaultLanguagePage,
9298
siteUrl,
9399
path
94100
};

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type PageOptions = {
1212
export type PluginOptions = {
1313
languages: string[];
1414
defaultLanguage: string;
15+
generateDefaultLanguagePage: boolean;
1516
path: string;
1617
redirect: boolean;
1718
siteUrl?: string;
@@ -26,6 +27,7 @@ export type I18NextContext = {
2627
routed: boolean;
2728
languages: string[];
2829
defaultLanguage: string;
30+
generateDefaultLanguagePage: boolean;
2931
originalPath: string;
3032
path: string;
3133
siteUrl?: string;

src/useI18next.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ export const useI18next = (ns?: Namespace, options?: UseTranslationOptions) => {
1212
const {i18n, t, ready} = useTranslation(ns, options);
1313
const context = useContext(I18nextContext);
1414

15-
const {routed, defaultLanguage} = context;
15+
const {routed, defaultLanguage, generateDefaultLanguagePage} = context;
1616

1717
const getLanguagePath = (language: string) => {
18-
return language !== defaultLanguage ? `/${language}` : '';
18+
return generateDefaultLanguagePage || language !== defaultLanguage ? `/${language}` : '';
1919
};
2020

2121
const removePrefix = (pathname: string) => {

0 commit comments

Comments
 (0)