@griddo/cx 1.75.178 → 1.75.180
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -14
- package/build/index.js +49 -0
- package/gatsby-browser.tsx +140 -0
- package/gatsby-config.ts +40 -0
- package/gatsby-node.ts +130 -0
- package/gatsby-ssr.tsx +63 -0
- package/index.js +4 -0
- package/package.json +119 -100
- package/scripts/build-reset.ts +9 -0
- package/scripts/griddo-exporter.ts +302 -0
- package/src/components/Head.tsx +207 -0
- package/src/components/template.tsx +90 -0
- package/src/components/types.ts +35 -0
- package/src/components/utils.ts +138 -0
- package/src/html.tsx +31 -0
- package/src/services/auth.ts +64 -0
- package/src/services/distributors.ts +153 -0
- package/src/services/domains.ts +27 -0
- package/src/services/navigation.ts +169 -0
- package/src/services/robots.ts +64 -0
- package/src/services/settings.ts +52 -0
- package/src/services/sites.ts +199 -0
- package/src/services/store-with-for-loop.ts +513 -0
- package/src/services/store-with-promise-all.ts +515 -0
- package/src/services/store.ts +513 -0
- package/src/types/api.ts +155 -0
- package/src/types/global.ts +72 -0
- package/src/types/navigation.ts +25 -0
- package/src/types/pages.ts +145 -0
- package/src/types/sites.ts +64 -0
- package/src/types/templates.ts +11 -0
- package/src/utils/api.ts +326 -0
- package/src/utils/cache.ts +114 -0
- package/src/utils/domains.ts +32 -0
- package/src/utils/folders.ts +147 -0
- package/src/utils/instance.ts +71 -0
- package/src/utils/pages.ts +534 -0
- package/src/utils/searches.ts +102 -0
- package/src/utils/shared.ts +131 -0
- package/src/utils/sites.ts +280 -0
- package/.babelrc +0 -7
- package/LICENSE +0 -1
- package/gatsby-browser.js +0 -115
- package/gatsby-config.js +0 -38
- package/gatsby-node.js +0 -273
- package/gatsby-ssr.js +0 -43
- package/scripts/griddo-exporter.js +0 -133
- package/src/api/index.js +0 -172
- package/src/components/template.js +0 -261
- package/src/html.js +0 -30
- package/src/images/readme.md +0 -1
- package/src/scripts/build-reset.js +0 -12
- package/src/services/auth.js +0 -44
- package/src/services/distributors.js +0 -85
- package/src/services/domains.js +0 -16
- package/src/services/navigation.js +0 -104
- package/src/services/robots.js +0 -37
- package/src/services/settings.js +0 -25
- package/src/services/sites.js +0 -110
- package/src/utils/cache.js +0 -70
- package/src/utils/component-lib-helpers.js +0 -56
- package/src/utils/dataLayer.js +0 -47
- package/src/utils/delay.js +0 -5
- package/src/utils/domains.js +0 -24
- package/src/utils/folders.js +0 -123
- package/src/utils/helpers.js +0 -144
- package/src/utils/index.js +0 -44
- package/src/utils/package.js +0 -20
- package/src/utils/pages.js +0 -236
- package/src/utils/searches.js +0 -62
- package/src/utils/sites.js +0 -207
- package/static/griddo-full-logo.png +0 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
4
|
+
/* eslint-disable node/shebang */
|
|
5
|
+
|
|
6
|
+
require("dotenv").config();
|
|
7
|
+
|
|
8
|
+
import { execSync } from "child_process";
|
|
9
|
+
import fs from "fs";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import pkgDir from "pkg-dir";
|
|
12
|
+
|
|
13
|
+
import { initCache } from "../src/utils/cache";
|
|
14
|
+
import { findDomains } from "../src/utils/domains";
|
|
15
|
+
|
|
16
|
+
const artifactsArchivable = ["dist", "assets", "apiCache", ".cache"];
|
|
17
|
+
const artifactsDisposable = ["public", ".store"];
|
|
18
|
+
|
|
19
|
+
// Where we are going to find export folders
|
|
20
|
+
const execBasePath = pkgDir.sync()!;
|
|
21
|
+
|
|
22
|
+
// Where we are going to find archived exports
|
|
23
|
+
const exportArchiveBasePath = path.resolve(execBasePath, "exports/sites");
|
|
24
|
+
|
|
25
|
+
// Where we are going to run the export command
|
|
26
|
+
const workingPath = pkgDir.sync(__dirname)!;
|
|
27
|
+
|
|
28
|
+
type Env = Record<string, unknown>;
|
|
29
|
+
|
|
30
|
+
// -----------------------------------------------------------------------------
|
|
31
|
+
// Process Runner
|
|
32
|
+
// -----------------------------------------------------------------------------
|
|
33
|
+
const getEnvRunner = (env: Env) => (command: string) => runner(command, env);
|
|
34
|
+
|
|
35
|
+
const runner = (command: string, env: Env = {}) =>
|
|
36
|
+
// TODO: Cuando esto falle, ejecutar `cleanAfterFail`
|
|
37
|
+
execSync(command, {
|
|
38
|
+
cwd: workingPath,
|
|
39
|
+
stdio: "inherit",
|
|
40
|
+
env: {
|
|
41
|
+
...process.env,
|
|
42
|
+
...env,
|
|
43
|
+
GRIDDO_EXPORTER: "true",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const getAssetPrefix = (domain: string) => {
|
|
48
|
+
// TODO: Usar asset_prefix del dominio
|
|
49
|
+
if (!process.env.GRIDDO_ASSET_PREFIX || !domain) return "";
|
|
50
|
+
|
|
51
|
+
if (!domain.startsWith("pro-")) return "";
|
|
52
|
+
|
|
53
|
+
return `${process.env.GRIDDO_ASSET_PREFIX}/${domain}`;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// -----------------------------------------------------------------------------
|
|
57
|
+
// Loggers
|
|
58
|
+
// -----------------------------------------------------------------------------
|
|
59
|
+
const logError = (...message: Array<any>) => console.info("error", ...message);
|
|
60
|
+
const logInfo = (...message: Array<any>) => console.info("info", ...message);
|
|
61
|
+
const logSuccess = (...message: Array<any>) =>
|
|
62
|
+
console.info("success", ...message);
|
|
63
|
+
const logWarning = (...message: Array<any>) =>
|
|
64
|
+
console.info("warning", ...message);
|
|
65
|
+
|
|
66
|
+
// -----------------------------------------------------------------------------
|
|
67
|
+
// Main Stuff
|
|
68
|
+
// -----------------------------------------------------------------------------
|
|
69
|
+
const domainExport = async (domain: string) => {
|
|
70
|
+
const runner = getDomainRunner(domain);
|
|
71
|
+
runner.init();
|
|
72
|
+
runner.restoreArtifacts();
|
|
73
|
+
runner.runExporter();
|
|
74
|
+
runner.archiveArtifacts();
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const launchExports = async () => {
|
|
78
|
+
logInfo("Griddo Exporter");
|
|
79
|
+
|
|
80
|
+
initCache();
|
|
81
|
+
|
|
82
|
+
const domains = await findDomains();
|
|
83
|
+
|
|
84
|
+
for (const domain of domains) {
|
|
85
|
+
logInfo(`Exporting domain ${domain}`);
|
|
86
|
+
await domainExport(domain);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const getDomainRunner = (domain: string) => {
|
|
91
|
+
const assetPrefix = getAssetPrefix(domain);
|
|
92
|
+
|
|
93
|
+
const run = getEnvRunner({
|
|
94
|
+
DOMAIN: domain,
|
|
95
|
+
ASSET_PREFIX: assetPrefix,
|
|
96
|
+
HAS_ASSET_DOMAIN: assetPrefix && assetPrefix !== "",
|
|
97
|
+
RENDERID: new Date().valueOf(),
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const init = () => {
|
|
101
|
+
logInfo(`Initializing ${domain} exporter...`);
|
|
102
|
+
|
|
103
|
+
cleanDirtyArtifactPaths();
|
|
104
|
+
createBaseExportPaths();
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const getArtifactPaths = (artifact = "") => {
|
|
108
|
+
const domainExportArchiveBasePath = path.resolve(
|
|
109
|
+
exportArchiveBasePath,
|
|
110
|
+
domain
|
|
111
|
+
);
|
|
112
|
+
const currentExportArchivePath = path.resolve(
|
|
113
|
+
domainExportArchiveBasePath,
|
|
114
|
+
artifact
|
|
115
|
+
);
|
|
116
|
+
const currentExportBackupPath = `${currentExportArchivePath}-BACKUP`;
|
|
117
|
+
const currentExportWorkingPath = path.resolve(workingPath, artifact);
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
domainExportArchiveBasePath,
|
|
121
|
+
currentExportArchivePath,
|
|
122
|
+
currentExportBackupPath,
|
|
123
|
+
currentExportWorkingPath,
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const cleanDirtyArtifactPaths = () => {
|
|
128
|
+
for (const artifact of [...artifactsArchivable, ...artifactsDisposable]) {
|
|
129
|
+
const { currentExportWorkingPath } = getArtifactPaths(artifact);
|
|
130
|
+
|
|
131
|
+
if (fs.existsSync(currentExportWorkingPath)) {
|
|
132
|
+
logWarning(`Deleting dirty ${currentExportWorkingPath}...`);
|
|
133
|
+
run(`rm -rf ${currentExportWorkingPath}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const createBaseExportPaths = () => {
|
|
139
|
+
const { domainExportArchiveBasePath } = getArtifactPaths();
|
|
140
|
+
|
|
141
|
+
if (!fs.existsSync(domainExportArchiveBasePath)) {
|
|
142
|
+
logInfo(`Creating ${domainExportArchiveBasePath}...`);
|
|
143
|
+
run(`mkdir -p ${domainExportArchiveBasePath}`);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const archiveExportArtifact = (artifact: string) => {
|
|
148
|
+
const { currentExportArchivePath, currentExportWorkingPath } =
|
|
149
|
+
getArtifactPaths(artifact);
|
|
150
|
+
|
|
151
|
+
logInfo(
|
|
152
|
+
`Moving files from ${currentExportWorkingPath} to ${currentExportArchivePath}...`
|
|
153
|
+
);
|
|
154
|
+
run(`mv ${currentExportWorkingPath} ${currentExportArchivePath}`);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const archiveArtifacts = () => {
|
|
158
|
+
for (const artifact of artifactsArchivable) {
|
|
159
|
+
const { currentExportWorkingPath, currentExportArchivePath } =
|
|
160
|
+
getArtifactPaths(artifact);
|
|
161
|
+
|
|
162
|
+
if (!fs.existsSync(currentExportWorkingPath)) {
|
|
163
|
+
logError(
|
|
164
|
+
"Source directory has not been created:",
|
|
165
|
+
currentExportWorkingPath
|
|
166
|
+
);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
createArtifactBackup(artifact);
|
|
172
|
+
archiveExportArtifact(artifact);
|
|
173
|
+
deleteArtifactBackup(artifact);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
logError(
|
|
176
|
+
`Error moving files to ${currentExportArchivePath}`,
|
|
177
|
+
error.message
|
|
178
|
+
);
|
|
179
|
+
restoreArtifactBackup(artifact);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const restoreArtifacts = () => {
|
|
186
|
+
for (const artifact of artifactsArchivable) {
|
|
187
|
+
const { currentExportArchivePath, currentExportWorkingPath } =
|
|
188
|
+
getArtifactPaths(artifact);
|
|
189
|
+
|
|
190
|
+
if (fs.existsSync(currentExportArchivePath)) {
|
|
191
|
+
logWarning(`Restaurando ${currentExportArchivePath}...`);
|
|
192
|
+
run(`cp -R ${currentExportArchivePath} ${currentExportWorkingPath}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
moveDistToPublic();
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const createArtifactBackup = (artifact: string) => {
|
|
200
|
+
const { currentExportArchivePath, currentExportBackupPath } =
|
|
201
|
+
getArtifactPaths(artifact);
|
|
202
|
+
|
|
203
|
+
if (fs.existsSync(currentExportArchivePath)) {
|
|
204
|
+
logInfo(`Creando backup de ${currentExportArchivePath}...`);
|
|
205
|
+
run(`mv ${currentExportArchivePath} ${currentExportBackupPath}`);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const restoreArtifactBackup = (artifact: string) => {
|
|
210
|
+
const { currentExportArchivePath, currentExportBackupPath } =
|
|
211
|
+
getArtifactPaths(artifact);
|
|
212
|
+
|
|
213
|
+
if (fs.existsSync(currentExportBackupPath)) {
|
|
214
|
+
logWarning(`Restaurando ${currentExportArchivePath}...`);
|
|
215
|
+
run(`mv ${currentExportBackupPath} ${currentExportArchivePath}`);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const deleteArtifactBackup = (artifact: string) => {
|
|
220
|
+
const { currentExportArchivePath, currentExportBackupPath } =
|
|
221
|
+
getArtifactPaths(artifact);
|
|
222
|
+
|
|
223
|
+
logInfo(`Eliminando backup de ${currentExportArchivePath}...`);
|
|
224
|
+
run(`rm -rf ${currentExportBackupPath}`);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const runExporter = () => {
|
|
228
|
+
console.log(
|
|
229
|
+
"\n",
|
|
230
|
+
"****************************<GATSBY>*********************",
|
|
231
|
+
"\n"
|
|
232
|
+
);
|
|
233
|
+
run("yarn export");
|
|
234
|
+
logSuccess("Your sites have been exported correctly");
|
|
235
|
+
console.log(
|
|
236
|
+
"\n",
|
|
237
|
+
"****************************</GATSBY>*********************",
|
|
238
|
+
"\n"
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
removeDisposableArtifacts();
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// TODO: Hacer que infra tire de `public` en vez de `dist` y quitar esto
|
|
245
|
+
const moveDistToPublic = () => {
|
|
246
|
+
const { currentExportWorkingPath: distPath } = getArtifactPaths("dist");
|
|
247
|
+
const { currentExportWorkingPath: publicPath } = getArtifactPaths("public");
|
|
248
|
+
|
|
249
|
+
if (fs.existsSync(distPath)) {
|
|
250
|
+
logWarning(`Moviendo ${distPath} a ${publicPath}...`);
|
|
251
|
+
run(`mv ${distPath} ${publicPath}`);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// TODO: Esto no debería hacerse desde infra
|
|
256
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
257
|
+
const movePublicToDist = () => {
|
|
258
|
+
const { currentExportWorkingPath: publicPath } = getArtifactPaths("public");
|
|
259
|
+
const { currentExportWorkingPath: distPath } = getArtifactPaths("dist");
|
|
260
|
+
|
|
261
|
+
if (fs.existsSync(publicPath)) {
|
|
262
|
+
logWarning(`Moviendo ${publicPath} a ${distPath}...`);
|
|
263
|
+
run(`mv ${publicPath} ${distPath}`);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const removeDisposableArtifacts = () => {
|
|
268
|
+
for (const artifact of artifactsDisposable) {
|
|
269
|
+
const { currentExportWorkingPath: artifactPath } =
|
|
270
|
+
getArtifactPaths(artifact);
|
|
271
|
+
|
|
272
|
+
if (fs.existsSync(artifactPath)) {
|
|
273
|
+
logWarning(`Borrando ${artifactPath}...`);
|
|
274
|
+
run(`rm -rf ${artifactPath}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
280
|
+
const cleanAfterFail = () => {
|
|
281
|
+
cleanDirtyArtifactPaths();
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
init,
|
|
286
|
+
getArtifactPaths,
|
|
287
|
+
archiveExportArtifact,
|
|
288
|
+
archiveArtifacts,
|
|
289
|
+
restoreArtifacts,
|
|
290
|
+
createArtifactBackup,
|
|
291
|
+
restoreArtifactBackup,
|
|
292
|
+
deleteArtifactBackup,
|
|
293
|
+
runExporter,
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
console.clear();
|
|
298
|
+
|
|
299
|
+
launchExports().catch((err) => {
|
|
300
|
+
console.error("ERROR", err?.stdout?.toString() || err);
|
|
301
|
+
process.exit(1);
|
|
302
|
+
});
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// Types
|
|
2
|
+
import type { CustomHeadProps } from "./types";
|
|
3
|
+
|
|
4
|
+
// Instance elements
|
|
5
|
+
import {
|
|
6
|
+
generateAutomaticDimensions,
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
} from "components";
|
|
9
|
+
|
|
10
|
+
// External libraries
|
|
11
|
+
import parse from "html-react-parser";
|
|
12
|
+
import * as React from "react";
|
|
13
|
+
|
|
14
|
+
// Utils
|
|
15
|
+
import { cleanCommaSeparated, composeAnalytics, formatImage } from "./utils";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Gatsby Head API
|
|
19
|
+
* https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-head/
|
|
20
|
+
*/
|
|
21
|
+
const Head = (props: CustomHeadProps) => {
|
|
22
|
+
const {
|
|
23
|
+
pageContext: {
|
|
24
|
+
griddoVersion,
|
|
25
|
+
locale,
|
|
26
|
+
openGraph,
|
|
27
|
+
page: { disableHrefLangs, fullUrl, defaultLang },
|
|
28
|
+
pageMetadata,
|
|
29
|
+
siteMetadata,
|
|
30
|
+
siteOptions,
|
|
31
|
+
},
|
|
32
|
+
} = props;
|
|
33
|
+
|
|
34
|
+
const metaRobots = cleanCommaSeparated(
|
|
35
|
+
`${pageMetadata?.index},${pageMetadata?.follow},${pageMetadata?.translate},${pageMetadata?.metasAdvanced}`
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const showMetaRobots =
|
|
39
|
+
!!metaRobots &&
|
|
40
|
+
(siteOptions?.showBasicMetaRobots || metaRobots !== "index,follow");
|
|
41
|
+
|
|
42
|
+
const { analyticsScript, analyticsDimensions } = composeAnalytics(
|
|
43
|
+
props,
|
|
44
|
+
generateAutomaticDimensions
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const emptyCodeScript = { props: { dangerouslySetInnerHTML: {} } };
|
|
48
|
+
|
|
49
|
+
const analyticsSrc =
|
|
50
|
+
(analyticsScript &&
|
|
51
|
+
analyticsScript.startsWith("UA-") &&
|
|
52
|
+
`https://www.googletagmanager.com/gtag/js?id=${analyticsScript}`) ||
|
|
53
|
+
null;
|
|
54
|
+
|
|
55
|
+
const analyticsCode =
|
|
56
|
+
analyticsScript && !analyticsSrc && analyticsScript.includes("<script")
|
|
57
|
+
? parse(analyticsScript)
|
|
58
|
+
: emptyCodeScript;
|
|
59
|
+
|
|
60
|
+
const fixedAnalyticsCode = Array.isArray(analyticsCode)
|
|
61
|
+
? analyticsCode.find((item) => item.type === "script") || emptyCodeScript
|
|
62
|
+
: analyticsCode;
|
|
63
|
+
|
|
64
|
+
const {
|
|
65
|
+
// TODO: Type this correctly
|
|
66
|
+
props: {
|
|
67
|
+
dangerouslySetInnerHTML: { __html: analyticsScriptCode },
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
69
|
+
children: analyticsScriptChildren,
|
|
70
|
+
...analyticsScriptProps
|
|
71
|
+
},
|
|
72
|
+
} = fixedAnalyticsCode as {
|
|
73
|
+
// TODO: Fix this custom inline weird type
|
|
74
|
+
props: {
|
|
75
|
+
dangerouslySetInnerHTML: { __html: React.ReactNode };
|
|
76
|
+
children: unknown;
|
|
77
|
+
src: string;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Resize favicon
|
|
82
|
+
const faviconResized = formatImage(siteMetadata?.favicon, 32, 32, "png");
|
|
83
|
+
|
|
84
|
+
// Validate options
|
|
85
|
+
const cleanPageLanguages =
|
|
86
|
+
pageMetadata?.pageLanguages?.filter((item) => item.isLive) || [];
|
|
87
|
+
|
|
88
|
+
const useCanonical =
|
|
89
|
+
!!pageMetadata?.canonical &&
|
|
90
|
+
!(
|
|
91
|
+
siteOptions?.avoidSelfReferenceCanonicals &&
|
|
92
|
+
pageMetadata?.canonical === fullUrl
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const useHrefLangs =
|
|
96
|
+
!(
|
|
97
|
+
siteOptions?.avoidHrefLangsOnCanonicals &&
|
|
98
|
+
useCanonical &&
|
|
99
|
+
pageMetadata?.canonical !== fullUrl
|
|
100
|
+
) &&
|
|
101
|
+
pageMetadata?.index === "index" &&
|
|
102
|
+
cleanPageLanguages.length > 1 &&
|
|
103
|
+
!disableHrefLangs;
|
|
104
|
+
|
|
105
|
+
const defaultLangId = defaultLang?.id || null;
|
|
106
|
+
const hrefLangXDefaultUrl =
|
|
107
|
+
(useHrefLangs &&
|
|
108
|
+
!siteOptions?.avoidHrefLangXDefault &&
|
|
109
|
+
defaultLangId &&
|
|
110
|
+
cleanPageLanguages.find((item) => item.languageId === defaultLangId)
|
|
111
|
+
?.url) ||
|
|
112
|
+
null;
|
|
113
|
+
|
|
114
|
+
const currentTime = new Date().toString();
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<>
|
|
118
|
+
{/* Uncomment with Gatsby 5.5.0 */}
|
|
119
|
+
{/* <html lang={locale} /> */}
|
|
120
|
+
|
|
121
|
+
{!!pageMetadata?.title && <title>{pageMetadata?.title}</title>}
|
|
122
|
+
{!!pageMetadata?.description && (
|
|
123
|
+
<meta name="description" content={pageMetadata?.description} />
|
|
124
|
+
)}
|
|
125
|
+
{siteOptions?.useMetaTitle && (
|
|
126
|
+
<meta name="title" content={pageMetadata?.title} />
|
|
127
|
+
)}
|
|
128
|
+
{useCanonical && <link rel="canonical" href={pageMetadata?.canonical} />}
|
|
129
|
+
{!!faviconResized && <link rel="icon" href={faviconResized} />}
|
|
130
|
+
|
|
131
|
+
{/* Alternate, solo si se indexa la página y tiene traducciones */}
|
|
132
|
+
{hrefLangXDefaultUrl && (
|
|
133
|
+
<link rel="alternate" href={hrefLangXDefaultUrl} hrefLang="x-default" />
|
|
134
|
+
)}
|
|
135
|
+
{useHrefLangs &&
|
|
136
|
+
cleanPageLanguages.map((item) => (
|
|
137
|
+
<link
|
|
138
|
+
key={item.pageId}
|
|
139
|
+
rel="alternate"
|
|
140
|
+
href={`${item.url}`}
|
|
141
|
+
hrefLang={item.locale?.replace(/_/g, "-")}
|
|
142
|
+
/>
|
|
143
|
+
))}
|
|
144
|
+
|
|
145
|
+
{/* Robots */}
|
|
146
|
+
{showMetaRobots && <meta name="robots" content={metaRobots} />}
|
|
147
|
+
|
|
148
|
+
{/* Open Graph */}
|
|
149
|
+
{!!siteMetadata?.title && (
|
|
150
|
+
<meta property="og:site_name" content={siteMetadata?.title} />
|
|
151
|
+
)}
|
|
152
|
+
{!!locale && <meta property="og:locale" content={locale} />}
|
|
153
|
+
{(!!openGraph?.title || !!pageMetadata?.title) && (
|
|
154
|
+
<meta
|
|
155
|
+
property="og:title"
|
|
156
|
+
content={openGraph?.title || pageMetadata?.title}
|
|
157
|
+
/>
|
|
158
|
+
)}
|
|
159
|
+
<meta property="og:type" content={openGraph?.type || "website"} />
|
|
160
|
+
{(!!openGraph?.description || !!pageMetadata?.description) && (
|
|
161
|
+
<meta
|
|
162
|
+
property="og:description"
|
|
163
|
+
content={openGraph?.description || pageMetadata?.description}
|
|
164
|
+
/>
|
|
165
|
+
)}
|
|
166
|
+
{!!openGraph?.image && (
|
|
167
|
+
<meta property="og:image" content={openGraph?.image} />
|
|
168
|
+
)}
|
|
169
|
+
<meta
|
|
170
|
+
property="og:url"
|
|
171
|
+
content={pageMetadata?.canonical || fullUrl || ""}
|
|
172
|
+
/>
|
|
173
|
+
|
|
174
|
+
{/* Twitter */}
|
|
175
|
+
<meta property="twitter:card" content="summary_large_image" />
|
|
176
|
+
{!!openGraph?.twitterImage && (
|
|
177
|
+
<meta property="twitter:image" content={openGraph?.twitterImage} />
|
|
178
|
+
)}
|
|
179
|
+
|
|
180
|
+
{/* Debug */}
|
|
181
|
+
{!siteOptions?.avoidDebugMetas && (
|
|
182
|
+
<meta
|
|
183
|
+
property="debug"
|
|
184
|
+
content={`Griddo v${griddoVersion} @ ${currentTime}}`}
|
|
185
|
+
/>
|
|
186
|
+
)}
|
|
187
|
+
|
|
188
|
+
{/* Data Layer */}
|
|
189
|
+
<script>{"window.dataLayer = window.dataLayer || [];"}</script>
|
|
190
|
+
{analyticsDimensions && (
|
|
191
|
+
<script>{`const {__HIDDEN, ...newDataLayer} = ${analyticsDimensions};newDataLayer && window.dataLayer && window.dataLayer.push(newDataLayer);`}</script>
|
|
192
|
+
)}
|
|
193
|
+
|
|
194
|
+
{/* Analytics with UA- */}
|
|
195
|
+
{analyticsSrc && <script src={analyticsSrc}></script>}
|
|
196
|
+
|
|
197
|
+
{/* {analyticsCode} */}
|
|
198
|
+
{(analyticsScriptProps?.src || analyticsScriptCode) && (
|
|
199
|
+
<script {...analyticsScriptProps} data-griddo-id={fullUrl}>
|
|
200
|
+
{analyticsScriptCode}
|
|
201
|
+
</script>
|
|
202
|
+
)}
|
|
203
|
+
</>
|
|
204
|
+
);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
export { Head };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Types
|
|
2
|
+
import type { Core } from "@griddo/core";
|
|
3
|
+
import type { TemplateProps } from "./types";
|
|
4
|
+
|
|
5
|
+
// Components and functions
|
|
6
|
+
import { Page as RenderGriddoPage } from "@griddo/core";
|
|
7
|
+
import { Link, navigate } from "gatsby";
|
|
8
|
+
|
|
9
|
+
// Instance elements
|
|
10
|
+
import {
|
|
11
|
+
components,
|
|
12
|
+
SiteProvider,
|
|
13
|
+
templates,
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
} from "components";
|
|
16
|
+
|
|
17
|
+
// External libraries
|
|
18
|
+
import * as React from "react";
|
|
19
|
+
import { Helmet } from "react-helmet";
|
|
20
|
+
|
|
21
|
+
// Gatsby Head
|
|
22
|
+
export { Head } from "./Head";
|
|
23
|
+
|
|
24
|
+
const Template = (data: TemplateProps) => {
|
|
25
|
+
const {
|
|
26
|
+
pageContext: {
|
|
27
|
+
BUILD_MODE,
|
|
28
|
+
cloudinaryName,
|
|
29
|
+
locale,
|
|
30
|
+
page,
|
|
31
|
+
siteLangs,
|
|
32
|
+
siteMetadata,
|
|
33
|
+
sitePages,
|
|
34
|
+
socials,
|
|
35
|
+
theme,
|
|
36
|
+
},
|
|
37
|
+
} = data;
|
|
38
|
+
|
|
39
|
+
const library = {
|
|
40
|
+
components,
|
|
41
|
+
templates,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const mappedTheme = theme || "default-theme";
|
|
45
|
+
|
|
46
|
+
const header = data.pageContext.header as Core.HeaderModule;
|
|
47
|
+
const footer = data.pageContext.footer as Core.FooterModule;
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<SiteProvider
|
|
51
|
+
apiUrl={page.apiUrl}
|
|
52
|
+
buildMode={BUILD_MODE}
|
|
53
|
+
cloudinaryCloudName={cloudinaryName}
|
|
54
|
+
instance={page.instance}
|
|
55
|
+
linkComponent={Link}
|
|
56
|
+
location={data.location}
|
|
57
|
+
navigate={navigate}
|
|
58
|
+
publicApiUrl={page.publicApiUrl}
|
|
59
|
+
renderer="gatsby"
|
|
60
|
+
siteId={page.site}
|
|
61
|
+
siteLangs={siteLangs}
|
|
62
|
+
siteMetadata={siteMetadata}
|
|
63
|
+
sitePages={sitePages}
|
|
64
|
+
socials={socials}
|
|
65
|
+
theme={mappedTheme}
|
|
66
|
+
>
|
|
67
|
+
{/*
|
|
68
|
+
Gatsby <Head> doesn't support anything outside of the <head> so we need to use <Helmet>
|
|
69
|
+
!! Support for editing <html> and <body> was added in gatsby@5.5.0. !!
|
|
70
|
+
TODO: Remove <Helmet> in Gatsby 5.5.0
|
|
71
|
+
*/}
|
|
72
|
+
<Helmet>
|
|
73
|
+
<html lang={locale} />
|
|
74
|
+
</Helmet>
|
|
75
|
+
|
|
76
|
+
{/* Render every page */}
|
|
77
|
+
<RenderGriddoPage
|
|
78
|
+
apiUrl={page.apiUrl}
|
|
79
|
+
content={page}
|
|
80
|
+
footer={footer}
|
|
81
|
+
header={header}
|
|
82
|
+
languageId={page.language}
|
|
83
|
+
library={library}
|
|
84
|
+
pageLanguages={page.pageLanguages}
|
|
85
|
+
/>
|
|
86
|
+
</SiteProvider>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export default Template;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Core } from "@griddo/core";
|
|
2
|
+
import type { HeadProps } from "gatsby";
|
|
3
|
+
import type { AllPagesResponse } from "../types/api";
|
|
4
|
+
import type { GatsbyPageObject } from "../types/pages";
|
|
5
|
+
|
|
6
|
+
export interface CustomHeadProps extends HeadProps {
|
|
7
|
+
pageContext: GatsbyPageObject["context"] & {
|
|
8
|
+
page: Core.Page & {
|
|
9
|
+
defaultLang: { id: number };
|
|
10
|
+
dimensions: { values: Record<string, unknown> };
|
|
11
|
+
disableHrefLangs: Array<number>;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface TemplateProps extends Omit<GatsbyPageObject, "context"> {
|
|
17
|
+
pageContext: GatsbyPageObject["context"] & {
|
|
18
|
+
page: Core.Page;
|
|
19
|
+
sitePages: AllPagesResponse;
|
|
20
|
+
};
|
|
21
|
+
location: {
|
|
22
|
+
pathname: string;
|
|
23
|
+
search: string;
|
|
24
|
+
hash: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface HtmlProps {
|
|
29
|
+
body: string;
|
|
30
|
+
bodyAttributes: React.HtmlHTMLAttributes<HTMLBodyElement>;
|
|
31
|
+
headComponents: React.ReactNode;
|
|
32
|
+
htmlAttributes: React.HtmlHTMLAttributes<HTMLHtmlElement>;
|
|
33
|
+
postBodyComponents: React.ReactNode;
|
|
34
|
+
preBodyComponents: React.ReactNode;
|
|
35
|
+
}
|