Skip to content

Commit 669bc8b

Browse files
committed
Add pages config that allows extracting language from path instead of generating pages automatically
Signed-off-by: Dmitriy Nevzorov <jimmy.lugat@gmail.com>
1 parent 067ab3f commit 669bc8b

File tree

5 files changed

+1206
-1651
lines changed

5 files changed

+1206
-1651
lines changed

.github/workflows/publish.yml

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

package.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
"gatsby-node.js",
3434
"gatsby-ssr.js"
3535
],
36+
"publishConfig": {
37+
"access": "public",
38+
"registry": "https://registry.npmjs.org/"
39+
},
3640
"scripts": {
3741
"build:ts": "babel src --out-dir dist --extensions .ts,.tsx",
3842
"build:defs": "tsc --declaration --outDir dist --emitDeclarationOnly",
@@ -47,19 +51,22 @@
4751
"@types/react": "^16.9.43",
4852
"@types/react-helmet": "^6.0.0",
4953
"babel-preset-gatsby-package": "^0.4.6",
50-
"gatsby": "^2.24.3",
54+
"gatsby": "^2.24.8",
5155
"husky": "^4.2.5",
5256
"i18next": "^19.6.2",
5357
"prettier": "^2.0.5",
5458
"pretty-quick": "^2.0.1",
59+
"react": "^16.13.1",
60+
"react-dom": "^16.13.1",
5561
"react-i18next": "^11.7.0",
5662
"release-it": "^13.6.5",
5763
"typescript": "^3.9.7"
5864
},
5965
"dependencies": {
6066
"bluebird": "^3.7.2",
6167
"browser-lang": "^0.1.0",
62-
"glob": "^7.1.6"
68+
"glob": "^7.1.6",
69+
"path-to-regexp": "^6.1.0"
6370
},
6471
"peerDependencies": {
6572
"gatsby": "^2.2.0",
@@ -84,7 +91,7 @@
8491
"release": true
8592
},
8693
"npm": {
87-
"publish": false
94+
"publish": true
8895
},
8996
"hooks": {
9097
"before:init": [

src/plugin/onCreatePage.ts

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {CreatePageArgs, Page} from 'gatsby';
33
import BP from 'bluebird';
44
import fs from 'fs';
55
import util from 'util';
6-
import {PageContext, PluginOptions, Resources} from '../types';
6+
import {match} from 'path-to-regexp';
7+
import {PageContext, PageOptions, PluginOptions, Resources} from '../types';
78

89
const readFile = util.promisify(fs.readFile);
910
const glob = util.promisify(_glob);
@@ -32,39 +33,82 @@ export const onCreatePage = async (
3233
}
3334

3435
const {createPage, deletePage} = actions;
35-
const {defaultLanguage = 'en', languages = ['en'], path} = pluginOptions;
36+
const {defaultLanguage = 'en', languages = ['en'], pages = []} = pluginOptions;
3637

37-
const generatePage = async (language: string, routed = false): Promise<Page<PageContext>> => {
38-
const resources = await getResources(path, language);
39-
const newPath = routed ? `${language}${page.path}` : page.path;
38+
type GeneratePageParams = {
39+
language: string;
40+
path?: string;
41+
originalPath?: string;
42+
routed?: boolean;
43+
pageOptions?: PageOptions;
44+
};
45+
const generatePage = async ({
46+
language,
47+
path = page.path,
48+
originalPath = page.path,
49+
routed = false,
50+
pageOptions
51+
}: GeneratePageParams): Promise<Page<PageContext>> => {
52+
const resources = await getResources(pluginOptions.path, language);
4053
return {
4154
...page,
42-
path: newPath,
55+
path,
4356
context: {
4457
...page.context,
4558
language,
4659
i18n: {
4760
language,
48-
languages,
61+
languages: pageOptions?.languages || languages,
4962
defaultLanguage,
5063
routed,
5164
resources,
52-
originalPath: page.path,
53-
path: newPath
65+
originalPath,
66+
path
5467
}
5568
}
5669
};
5770
};
5871

59-
const newPage = await generatePage(defaultLanguage);
72+
const pageOptions = pages.find((opt) => match(opt.matchPath)(page.path));
73+
74+
let newPage;
75+
let alternativeLanguages = languages.filter((lng) => lng !== defaultLanguage);
76+
77+
if (pageOptions?.excludeLanguages) {
78+
alternativeLanguages = alternativeLanguages.filter(
79+
(lng) => !pageOptions?.excludeLanguages?.includes(lng)
80+
);
81+
}
82+
83+
if (pageOptions?.languages) {
84+
alternativeLanguages = pageOptions.languages.filter((lng) => lng !== defaultLanguage);
85+
}
86+
87+
if (pageOptions?.getLanguageFromPath) {
88+
const result = match<{lang: string}>(pageOptions.matchPath)(page.path);
89+
if (!result) return;
90+
const language = result.params.lang || defaultLanguage;
91+
const originalPath = page.path.replace(`/${language}`, '');
92+
const routed = Boolean(result.params.lang);
93+
newPage = await generatePage({language, originalPath, routed, pageOptions});
94+
if (routed || !pageOptions.excludeLanguages) {
95+
alternativeLanguages = [];
96+
}
97+
} else {
98+
newPage = await generatePage({language: defaultLanguage, pageOptions});
99+
}
100+
60101
try {
61102
deletePage(page);
62103
} catch {}
63104
createPage(newPage);
64105

65-
await BP.map(languages, async (lng) => {
66-
if (lng === defaultLanguage) return;
67-
const localePage = await generatePage(lng, true);
106+
await BP.map(alternativeLanguages, async (lng) => {
107+
const localePage = await generatePage({
108+
language: lng,
109+
path: `${lng}${page.path}`,
110+
routed: true
111+
});
68112
const regexp = new RegExp('/404/?$');
69113
if (regexp.test(localePage.path)) {
70114
localePage.matchPath = `/${lng}/*`;

src/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@ import {InitOptions} from 'i18next';
22

33
export const LANGUAGE_KEY = 'gatsby-i18next-language';
44

5+
export type PageOptions = {
6+
matchPath: string;
7+
getLanguageFromPath?: boolean;
8+
excludeLanguages?: string[];
9+
languages?: string[];
10+
};
11+
512
export type PluginOptions = {
613
languages: string[];
714
defaultLanguage: string;
815
path: string;
916
redirect: boolean;
1017
siteUrl?: string;
1118
i18nextOptions: InitOptions;
19+
pages: Array<PageOptions>;
1220
};
1321

1422
export type Resources = Record<string, Record<string, Record<string, string>>>;

0 commit comments

Comments
 (0)