Author SHA1 Message Date
andwati c18147034f Allow Cloudflare Web Analytics in the CSP
Cloudflare auto-injects beacon.min.js, which the CSP was blocking.
2026-10-07 11:29:27 +03:00
andwati 916a95f692 Restore the original GA measurement ID
G-9XLTKZF07C is the ID Google Analytics issues for this property.
2026-10-07 11:26:45 +03:00
andwati e0f0ae7c7f Fix GA measurement ID and CSP, redirect legacy Hugo URLs
Use the GA4 measurement ID Search Console expects and allow Google Tag Manager/Analytics in the CSP so gtag is not blocked. Add 301s from the old /posts, /writings, /tags, /archive, /about and /index.xml URLs to their current routes to clear the Search Console 404s.
2026-10-07 11:20:31 +03:00
andwati 2c19e7ed1a Tidy gtag snippet indentation 2026-09-30 14:19:21 +03:00
andwati a06a93019f Only load analytics in production 2026-09-30 14:19:13 +03:00
andwati 77cc86ddf9 Add Google Analytics via next/script 2026-09-30 14:17:41 +03:00
andwatiandGitHub 2960dc622f Merge pull request #5 from andwati/feat/nextjs-site
Replace Astro/Strapi site with Next.js static export
2026-09-30 13:55:52 +03:00
2 changed files with 76 additions and 2 deletions
+18 -1
View File
@@ -58,6 +58,9 @@ const websiteLd = {
author: { "@type": "Person", name: site.name }, author: { "@type": "Person", name: site.name },
}; };
const isProd = process.env.NODE_ENV === "production";
const gaId = "G-9XLTKZF07C";
const umamiScript = process.env.PUBLIC_UMAMI_SCRIPT_URL; const umamiScript = process.env.PUBLIC_UMAMI_SCRIPT_URL;
const umamiId = process.env.PUBLIC_UMAMI_WEBSITE_ID; const umamiId = process.env.PUBLIC_UMAMI_WEBSITE_ID;
@@ -81,7 +84,21 @@ export default function RootLayout({ children }: LayoutProps<"/">) {
<body> <body>
<JsonLd data={websiteLd} /> <JsonLd data={websiteLd} />
<Layout>{children}</Layout> <Layout>{children}</Layout>
{umamiScript && umamiId && ( {isProd && (
<>
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${gaId}`}
strategy="afterInteractive"
/>
<Script id="google-analytics" strategy="afterInteractive">
{`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gaId}');`}
</Script>
</>
)}
{isProd && umamiScript && umamiId && (
<Script defer src={umamiScript} data-website-id={umamiId} /> <Script defer src={umamiScript} data-website-id={umamiId} />
)} )}
</body> </body>
+58 -1
View File
@@ -7,10 +7,67 @@ ignore-hidden-files = false
[advanced] [advanced]
# Legacy Hugo URLs (/posts, /writings, /tags, ...) -> current routes. First match wins,
# so the trailing-slash variants Google crawled come before the bare ones.
[[advanced.redirects]]
source = "/posts/page/{*}/"
destination = "/writing"
kind = 301
[[advanced.redirects]]
source = "/posts/page/{*}"
destination = "/writing"
kind = 301
[[advanced.redirects]]
source = "/{posts,writings,tags,archive}/"
destination = "/writing"
kind = 301
[[advanced.redirects]]
source = "/{posts,writings}/{*}/"
destination = "/writing/$2"
kind = 301
[[advanced.redirects]]
source = "/{posts,writings}/{*}"
destination = "/writing/$2"
kind = 301
[[advanced.redirects]]
source = "/{posts,writings,tags,archive}"
destination = "/writing"
kind = 301
[[advanced.redirects]]
source = "/tags/{*}/"
destination = "/writing"
kind = 301
[[advanced.redirects]]
source = "/tags/{*}"
destination = "/writing"
kind = 301
[[advanced.redirects]]
source = "/about/"
destination = "/"
kind = 301
[[advanced.redirects]]
source = "/about"
destination = "/"
kind = 301
[[advanced.redirects]]
source = "/index.xml"
destination = "/rss.xml"
kind = 301
[[advanced.headers]] [[advanced.headers]]
source = "**" source = "**"
[advanced.headers.headers] [advanced.headers.headers]
Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline' https://utteranc.es https://analytics.andwati.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self' https://analytics.andwati.com; frame-src https://www.youtube-nocookie.com https://utteranc.es; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests" Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline' https://utteranc.es https://analytics.andwati.com https://www.googletagmanager.com https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://www.google-analytics.com https://www.googletagmanager.com; font-src 'self'; connect-src 'self' https://cloudflareinsights.com https://analytics.andwati.com https://www.google-analytics.com https://*.google-analytics.com https://*.analytics.google.com https://www.googletagmanager.com; frame-src https://www.youtube-nocookie.com https://utteranc.es; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests"
X-Frame-Options = "DENY" X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff" X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin" Referrer-Policy = "strict-origin-when-cross-origin"