@griddo/cx 1.75.179 → 1.75.181

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.
Files changed (72) hide show
  1. package/README.md +22 -14
  2. package/build/index.js +65 -0
  3. package/gatsby-browser.tsx +140 -0
  4. package/gatsby-config.ts +40 -0
  5. package/gatsby-node.ts +134 -0
  6. package/gatsby-ssr.tsx +63 -0
  7. package/index.js +4 -0
  8. package/package.json +119 -100
  9. package/scripts/build-reset.ts +9 -0
  10. package/scripts/griddo-exporter.ts +305 -0
  11. package/src/components/Head.tsx +207 -0
  12. package/src/components/template.tsx +90 -0
  13. package/src/components/types.ts +35 -0
  14. package/src/components/utils.ts +138 -0
  15. package/src/html.tsx +31 -0
  16. package/src/services/auth.ts +64 -0
  17. package/src/services/distributors.ts +153 -0
  18. package/src/services/domains.ts +27 -0
  19. package/src/services/navigation.ts +169 -0
  20. package/src/services/robots.ts +64 -0
  21. package/src/services/settings.ts +52 -0
  22. package/src/services/sites.ts +196 -0
  23. package/src/services/store-with-for-loop.ts +513 -0
  24. package/src/services/store-with-promise-all.ts +515 -0
  25. package/src/services/store.ts +513 -0
  26. package/src/types/api.ts +184 -0
  27. package/src/types/global.ts +64 -0
  28. package/src/types/navigation.ts +25 -0
  29. package/src/types/pages.ts +145 -0
  30. package/src/types/sites.ts +64 -0
  31. package/src/types/templates.ts +11 -0
  32. package/src/utils/api.ts +325 -0
  33. package/src/utils/cache.ts +114 -0
  34. package/src/utils/domains.ts +32 -0
  35. package/src/utils/folders.ts +147 -0
  36. package/src/utils/instance.ts +71 -0
  37. package/src/utils/pages.ts +534 -0
  38. package/src/utils/searches.ts +103 -0
  39. package/src/utils/shared.ts +155 -0
  40. package/src/utils/sites.ts +279 -0
  41. package/.babelrc +0 -7
  42. package/LICENSE +0 -1
  43. package/gatsby-browser.js +0 -115
  44. package/gatsby-config.js +0 -38
  45. package/gatsby-node.js +0 -273
  46. package/gatsby-ssr.js +0 -43
  47. package/scripts/griddo-exporter.js +0 -133
  48. package/src/api/index.js +0 -185
  49. package/src/components/template.js +0 -261
  50. package/src/html.js +0 -30
  51. package/src/images/readme.md +0 -1
  52. package/src/scripts/build-reset.js +0 -12
  53. package/src/services/auth.js +0 -44
  54. package/src/services/distributors.js +0 -85
  55. package/src/services/domains.js +0 -16
  56. package/src/services/navigation.js +0 -104
  57. package/src/services/robots.js +0 -37
  58. package/src/services/settings.js +0 -25
  59. package/src/services/sites.js +0 -110
  60. package/src/utils/cache.js +0 -70
  61. package/src/utils/component-lib-helpers.js +0 -56
  62. package/src/utils/dataLayer.js +0 -47
  63. package/src/utils/delay.js +0 -5
  64. package/src/utils/domains.js +0 -24
  65. package/src/utils/folders.js +0 -123
  66. package/src/utils/helpers.js +0 -144
  67. package/src/utils/index.js +0 -44
  68. package/src/utils/package.js +0 -20
  69. package/src/utils/pages.js +0 -236
  70. package/src/utils/searches.js +0 -62
  71. package/src/utils/sites.js +0 -207
  72. package/static/griddo-full-logo.png +0 -0
@@ -0,0 +1,305 @@
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
+ // External libraries
9
+ import chalk from "chalk";
10
+ import { execSync } from "child_process";
11
+ import fs from "fs";
12
+ import path from "path";
13
+ import pkgDir from "pkg-dir";
14
+
15
+ // Utils
16
+ import { initCache } from "../src/utils/cache";
17
+ import { findDomains } from "../src/utils/domains";
18
+ import { exporterLogo as splash } from "../src/utils/shared";
19
+
20
+ // Envs
21
+ const artifactsArchivable = ["dist", "assets", "apiCache", ".cache"];
22
+ const artifactsDisposable = ["public", ".store"];
23
+
24
+ // Where we are going to find export folders
25
+ const execBasePath = pkgDir.sync()!;
26
+
27
+ // Where we are going to find archived exports
28
+ const exportArchiveBasePath = path.resolve(execBasePath, "exports/sites");
29
+
30
+ // Where we are going to run the export command
31
+ const workingPath = pkgDir.sync(__dirname)!;
32
+
33
+ // Types
34
+ type Env = Record<string, unknown>;
35
+
36
+ // -----------------------------------------------------------------------------
37
+ // Process Runner
38
+ // -----------------------------------------------------------------------------
39
+ const getEnvRunner = (env: Env) => (command: string) => runner(command, env);
40
+
41
+ const runner = (command: string, env: Env = {}) =>
42
+ // TODO: Cuando esto falle, ejecutar `cleanAfterFail`
43
+ execSync(command, {
44
+ cwd: workingPath,
45
+ stdio: "inherit",
46
+ env: {
47
+ ...process.env,
48
+ ...env,
49
+ GRIDDO_EXPORTER: "true",
50
+ },
51
+ });
52
+
53
+ const getAssetPrefix = (domain: string) => {
54
+ // TODO: Usar asset_prefix del dominio
55
+ if (!process.env.GRIDDO_ASSET_PREFIX || !domain) return "";
56
+
57
+ if (!domain.startsWith("pro-")) return "";
58
+
59
+ return `${process.env.GRIDDO_ASSET_PREFIX}/${domain}`;
60
+ };
61
+
62
+ // -----------------------------------------------------------------------------
63
+ // Loggers
64
+ // -----------------------------------------------------------------------------
65
+ const logError = (...message: Array<any>) => console.log(...message);
66
+ const logInfo = (...message: Array<any>) => console.log(...message);
67
+ const logSuccess = (...message: Array<any>) => console.log(...message);
68
+ const logWarning = (...message: Array<any>) => console.log(...message);
69
+
70
+ // -----------------------------------------------------------------------------
71
+ // Main Stuff
72
+ // -----------------------------------------------------------------------------
73
+ const domainExport = async (domain: string) => {
74
+ const runner = getDomainRunner(domain);
75
+ runner.init();
76
+ runner.restoreArtifacts();
77
+ runner.runExporter();
78
+ runner.archiveArtifacts();
79
+ };
80
+
81
+ const launchExports = async () => {
82
+ splash();
83
+ initCache();
84
+
85
+ const domains = await findDomains();
86
+
87
+ for (const domain of domains) {
88
+ logInfo(`️🚢 Exporting domain ${chalk.underline(domain)}`);
89
+ await domainExport(domain);
90
+ }
91
+ };
92
+
93
+ const getDomainRunner = (domain: string) => {
94
+ const assetPrefix = getAssetPrefix(domain);
95
+
96
+ const run = getEnvRunner({
97
+ DOMAIN: domain,
98
+ ASSET_PREFIX: assetPrefix,
99
+ HAS_ASSET_DOMAIN: assetPrefix && assetPrefix !== "",
100
+ RENDERID: new Date().valueOf(),
101
+ });
102
+
103
+ const init = () => {
104
+ logInfo(`🚀 Initializing ${chalk.underline(domain)} exporter`);
105
+
106
+ cleanDirtyArtifactPaths();
107
+ createBaseExportPaths();
108
+ };
109
+
110
+ const getArtifactPaths = (artifact = "") => {
111
+ const domainExportArchiveBasePath = path.resolve(
112
+ exportArchiveBasePath,
113
+ domain
114
+ );
115
+ const currentExportArchivePath = path.resolve(
116
+ domainExportArchiveBasePath,
117
+ artifact
118
+ );
119
+ const currentExportBackupPath = `${currentExportArchivePath}-BACKUP`;
120
+ const currentExportWorkingPath = path.resolve(workingPath, artifact);
121
+
122
+ return {
123
+ domainExportArchiveBasePath,
124
+ currentExportArchivePath,
125
+ currentExportBackupPath,
126
+ currentExportWorkingPath,
127
+ };
128
+ };
129
+
130
+ const cleanDirtyArtifactPaths = () => {
131
+ for (const artifact of [...artifactsArchivable, ...artifactsDisposable]) {
132
+ const { currentExportWorkingPath } = getArtifactPaths(artifact);
133
+
134
+ if (fs.existsSync(currentExportWorkingPath)) {
135
+ logWarning(`🧹 Cleanup dirty ${chalk.gray(currentExportWorkingPath)}`);
136
+ run(`rm -rf ${currentExportWorkingPath}`);
137
+ }
138
+ }
139
+ };
140
+
141
+ const createBaseExportPaths = () => {
142
+ const { domainExportArchiveBasePath } = getArtifactPaths();
143
+
144
+ if (!fs.existsSync(domainExportArchiveBasePath)) {
145
+ logInfo(`✨ Creating ${domainExportArchiveBasePath}`);
146
+ run(`mkdir -p ${domainExportArchiveBasePath}`);
147
+ }
148
+ };
149
+
150
+ const archiveExportArtifact = (artifact: string) => {
151
+ const { currentExportArchivePath, currentExportWorkingPath } =
152
+ getArtifactPaths(artifact);
153
+
154
+ logInfo(
155
+ `🚚 Moving files from ${chalk.gray(
156
+ currentExportWorkingPath
157
+ )} to ${chalk.gray(currentExportArchivePath)}`
158
+ );
159
+ run(`mv ${currentExportWorkingPath} ${currentExportArchivePath}`);
160
+ };
161
+
162
+ const archiveArtifacts = () => {
163
+ for (const artifact of artifactsArchivable) {
164
+ const { currentExportWorkingPath, currentExportArchivePath } =
165
+ getArtifactPaths(artifact);
166
+
167
+ if (!fs.existsSync(currentExportWorkingPath)) {
168
+ logError(
169
+ "📁 Source directory has not been created:",
170
+ currentExportWorkingPath
171
+ );
172
+ continue;
173
+ }
174
+
175
+ try {
176
+ createArtifactBackup(artifact);
177
+ archiveExportArtifact(artifact);
178
+ deleteArtifactBackup(artifact);
179
+ } catch (error) {
180
+ logError(
181
+ `🚚 Error moving files to ${currentExportArchivePath}`,
182
+ error.message
183
+ );
184
+ restoreArtifactBackup(artifact);
185
+ continue;
186
+ }
187
+ }
188
+ };
189
+
190
+ const restoreArtifacts = () => {
191
+ for (const artifact of artifactsArchivable) {
192
+ const { currentExportArchivePath, currentExportWorkingPath } =
193
+ getArtifactPaths(artifact);
194
+
195
+ if (fs.existsSync(currentExportArchivePath)) {
196
+ logWarning(`️♻️ Restoring ${chalk.gray(currentExportArchivePath)}`);
197
+ run(`cp -R ${currentExportArchivePath} ${currentExportWorkingPath}`);
198
+ }
199
+ }
200
+
201
+ moveDistToPublic();
202
+ };
203
+
204
+ const createArtifactBackup = (artifact: string) => {
205
+ const { currentExportArchivePath, currentExportBackupPath } =
206
+ getArtifactPaths(artifact);
207
+
208
+ if (fs.existsSync(currentExportArchivePath)) {
209
+ logInfo(`💿 Creating backup of ${chalk.gray(currentExportArchivePath)}`);
210
+ run(`mv ${currentExportArchivePath} ${currentExportBackupPath}`);
211
+ }
212
+ };
213
+
214
+ const restoreArtifactBackup = (artifact: string) => {
215
+ const { currentExportArchivePath, currentExportBackupPath } =
216
+ getArtifactPaths(artifact);
217
+
218
+ if (fs.existsSync(currentExportBackupPath)) {
219
+ logWarning(
220
+ `️♻️ Restoring backup ${chalk.gray(currentExportArchivePath)}`
221
+ );
222
+ run(`mv ${currentExportBackupPath} ${currentExportArchivePath}`);
223
+ }
224
+ };
225
+
226
+ const deleteArtifactBackup = (artifact: string) => {
227
+ const { currentExportArchivePath, currentExportBackupPath } =
228
+ getArtifactPaths(artifact);
229
+
230
+ logWarning(`️❌ Removing backup ${chalk.gray(currentExportArchivePath)}`);
231
+ run(`rm -rf ${currentExportBackupPath}`);
232
+ };
233
+
234
+ const runExporter = () => {
235
+ console.log(`\n${chalk.black(chalk.bgGreen(" Gatsby (start) "))}\n`);
236
+
237
+ run("yarn export");
238
+ logSuccess("Your sites have been exported correctly");
239
+
240
+ console.log(`\n${chalk.black(chalk.bgGreen(" Gatsby (end) "))}\n`);
241
+
242
+ removeDisposableArtifacts();
243
+ };
244
+
245
+ // TODO: Hacer que infra tire de `public` en vez de `dist` y quitar esto
246
+ const moveDistToPublic = () => {
247
+ const { currentExportWorkingPath: distPath } = getArtifactPaths("dist");
248
+ const { currentExportWorkingPath: publicPath } = getArtifactPaths("public");
249
+
250
+ if (fs.existsSync(distPath)) {
251
+ logWarning(
252
+ `🚚 Moving ${chalk.gray(distPath)} to ${chalk.gray(publicPath)}`
253
+ );
254
+ run(`mv ${distPath} ${publicPath}`);
255
+ }
256
+ };
257
+
258
+ // TODO: Esto no debería hacerse desde infra
259
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
260
+ const movePublicToDist = () => {
261
+ const { currentExportWorkingPath: publicPath } = getArtifactPaths("public");
262
+ const { currentExportWorkingPath: distPath } = getArtifactPaths("dist");
263
+
264
+ if (fs.existsSync(publicPath)) {
265
+ logWarning(`🚚 Moving ${publicPath} to ${distPath}`);
266
+ run(`mv ${publicPath} ${distPath}`);
267
+ }
268
+ };
269
+
270
+ const removeDisposableArtifacts = () => {
271
+ for (const artifact of artifactsDisposable) {
272
+ const { currentExportWorkingPath: artifactPath } =
273
+ getArtifactPaths(artifact);
274
+
275
+ if (fs.existsSync(artifactPath)) {
276
+ logWarning(`❌ Removing ${chalk.gray(artifactPath)}`);
277
+ run(`rm -rf ${artifactPath}`);
278
+ }
279
+ }
280
+ };
281
+
282
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
283
+ const cleanAfterFail = () => {
284
+ cleanDirtyArtifactPaths();
285
+ };
286
+
287
+ return {
288
+ init,
289
+ getArtifactPaths,
290
+ archiveExportArtifact,
291
+ archiveArtifacts,
292
+ restoreArtifacts,
293
+ createArtifactBackup,
294
+ restoreArtifactBackup,
295
+ deleteArtifactBackup,
296
+ runExporter,
297
+ };
298
+ };
299
+
300
+ console.clear();
301
+
302
+ launchExports().catch((err) => {
303
+ console.error("❌ ERROR", err?.stdout?.toString() || err);
304
+ process.exit(1);
305
+ });
@@ -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
+ }