Skip to content

Commit 178a0c6

Browse files
committed
Merge branch '604-update-footer-with-links-and-email' of https://github.com/speedandfunction/website into 604-update-footer-with-links-and-email
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
2 parents 5e95751 + fc701f5 commit 178a0c6

8 files changed

Lines changed: 106 additions & 2 deletions

File tree

website/app.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,15 @@ function createAposConfig() {
3434
},
3535
},
3636
},
37-
37+
// GTM setup and dependencies
38+
'@apostrophecms/seo': {
39+
options: {
40+
googleTagManager: {
41+
id: process.env.GOOGLE_TAG_MANAGER_ID,
42+
},
43+
},
44+
},
45+
'@apostrophecms/global': {},
3846
// Make getEnv function available to templates
3947
'@apostrophecms/template': {
4048
options: {

website/modules/@apostrophecms/global/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ module.exports = {
120120
},
121121
},
122122
},
123+
// SEO fields
124+
seoGoogleTagManager: {
125+
label: 'Google Tag Manager ID',
126+
type: 'string',
127+
help: 'Enter your GTM container ID (e.g., GTM-XXXXXXX)',
128+
},
123129
},
124130
group: {
125131
navs: {
@@ -130,6 +136,10 @@ module.exports = {
130136
label: 'Footer',
131137
fields: ['comAddress', 'footerLinks', 'socialMediaLinks', 'footerForm'],
132138
},
139+
seo: {
140+
label: 'SEO & Analytics',
141+
fields: ['seoGoogleTagManager'],
142+
},
133143
},
134144
},
135145
};
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module.exports = {
2+
improve: '@apostrophecms/seo',
3+
init(self) {
4+
// Ensure SEO components are injected into the template
5+
self.apos.template.prepend('body', '@apostrophecms/seo:tagManagerBody');
6+
self.apos.template.append('head', '@apostrophecms/seo:tagManagerHead');
7+
self.apos.template.prepend('head', '@apostrophecms/seo:metaHead');
8+
},
9+
components(self) {
10+
/*
11+
* Resolve GTM ID from global override or module options and validate it
12+
*/
13+
const sanitizeGtmId = (id) => {
14+
const value = String(id || '').trim();
15+
if (/^gtm-[\da-z]+$/iu.test(value)) {
16+
return value.toUpperCase();
17+
}
18+
return '';
19+
};
20+
const resolveGtmId = (req) => {
21+
const fromGlobal = req?.data?.global?.seoGoogleTagManager;
22+
const fromOptions = self.options?.googleTagManager?.id;
23+
const candidate =
24+
(fromGlobal && String(fromGlobal).trim()) ||
25+
(fromOptions && String(fromOptions).trim());
26+
return sanitizeGtmId(candidate);
27+
};
28+
29+
return {
30+
metaHead(req, data) {
31+
// Only on front-end page requests
32+
if (!req?.data?.page) {
33+
return {};
34+
}
35+
return {};
36+
},
37+
tagManagerBody(req, data) {
38+
if (!req?.data?.page) {
39+
return {};
40+
}
41+
const gtmId = resolveGtmId(req);
42+
if (gtmId) {
43+
return { gtmId };
44+
}
45+
return {};
46+
},
47+
tagManagerHead(req, data) {
48+
if (!req?.data?.page) {
49+
return {};
50+
}
51+
const gtmId = resolveGtmId(req);
52+
if (gtmId) {
53+
return { gtmId };
54+
}
55+
return {};
56+
},
57+
};
58+
},
59+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{# Meta head template for SEO - placeholder for other meta tags #}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% if data.gtmId %}
2+
<!-- Google Tag Manager (noscript) -->
3+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ data.gtmId }}"
4+
height="0" width="0" style="display:none;visibility:hidden" title="Google Tag Manager"></iframe></noscript>
5+
<!-- End Google Tag Manager (noscript) -->
6+
{% endif %}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% if data.gtmId %}
2+
<!-- Google Tag Manager -->
3+
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
4+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
5+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
6+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
7+
})(window,document,'script','dataLayer','{{ data.gtmId }}');</script>
8+
<!-- End Google Tag Manager -->
9+
{% endif %}

website/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

website/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"dependencies": {
4141
"@apostrophecms/form": "^1.4.2",
4242
"@apostrophecms/import-export": "^3.2.0",
43+
"@apostrophecms/seo": "^1.3.1",
4344
"@barba/core": "^2.10.3",
4445
"abort-controller": "^3.0.0",
4546
"apostrophe": "^4.17.0",
@@ -51,8 +52,8 @@
5152
"jest-environment-jsdom": "^30.0.0-beta.3",
5253
"lodash": "^4.17.21",
5354
"lozad": "^1.16.0",
54-
"node-fetch": "^2.6.7",
5555
"mongodb": "^6.17.0",
56+
"node-fetch": "^2.6.7",
5657
"normalize.css": "^8.0.1",
5758
"postmark": "^4.0.5",
5859
"swiper": "^11.2.6",

0 commit comments

Comments
 (0)