From 6ac6098668f98a4953ace998efd9606f5d8ea596 Mon Sep 17 00:00:00 2001 From: Wayne Sutton Date: Wed, 24 Dec 2025 00:13:10 -0800 Subject: [PATCH] fix(ai): remove Link header from /raw/* and use window.location.origin for raw URLs - Remove Link header from global headers scope, apply only to /index.html - Remove X-Robots-Tag noindex from /raw/* to allow AI crawler indexing - Use window.location.origin instead of props.url for raw markdown URL construction - Ensures correct URLs even when props.url points to canonical/deploy preview domains - Fixes ChatGPT/Perplexity fetch failures on /raw/*.md endpoints --- changelog.md | 28 ++++++++++++++++++++++++++++ netlify.toml | 11 +++++++++-- src/components/CopyPageDropdown.tsx | 26 ++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index cf847e7..b653475 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [1.24.8] - 2025-12-23 + +### Fixed + +- Raw markdown URL construction now uses `window.location.origin` instead of `props.url` + - Prevents incorrect URLs when `props.url` points to canonical/deploy preview domains + - Uses `new URL()` constructor for proper absolute URL building + - Ensures raw URLs always match the current page origin + - Applied to both AI service links and "View as Markdown" option + +### Technical + +- `src/components/CopyPageDropdown.tsx`: Changed raw URL construction from `new URL(props.url).origin` to `window.location.origin` with `new URL()` constructor + +## [1.24.7] - 2025-12-23 + +### Fixed + +- Removed `Link` header from `/raw/*` endpoints to fix AI crawler fetch failures + - Netlify merges headers, so global `Link` header was being applied to `/raw/*` despite specific block + - Moved `Link` header from global `/*` scope to `/index.html` only + - Removed `X-Robots-Tag = "noindex"` from `/raw/*` to allow AI crawlers to index raw content + - Raw markdown files now have clean headers optimized for AI consumption + +### Technical + +- `netlify.toml`: Removed `Link` from global headers, added specific `/index.html` block, removed `noindex` from `/raw/*` + ## [1.24.6] - 2025-12-23 ### Added diff --git a/netlify.toml b/netlify.toml index ae777be..5fe7ede 100644 --- a/netlify.toml +++ b/netlify.toml @@ -76,7 +76,7 @@ "/openapi.yaml" ] -# Security and SEO headers +# Security and SEO headers (global, excludes /raw/*) [[headers]] for = "/*" [headers.values] @@ -84,16 +84,23 @@ X-Content-Type-Options = "nosniff" X-XSS-Protection = "1; mode=block" Referrer-Policy = "strict-origin-when-cross-origin" + # Link header removed from global scope to avoid applying to /raw/* + +# Link header for SPA entry point only +[[headers]] + for = "/index.html" + [headers.values] Link = "; rel=\"author\"" # Raw markdown files - AI friendly headers +# No Link header, no noindex - optimized for AI crawlers [[headers]] for = "/raw/*" [headers.values] Content-Type = "text/markdown; charset=utf-8" Access-Control-Allow-Origin = "*" Cache-Control = "public, max-age=3600" - X-Robots-Tag = "noindex" + # Removed X-Robots-Tag = "noindex" - AI crawlers need to index raw content [context.production.environment] NODE_ENV = "production" diff --git a/src/components/CopyPageDropdown.tsx b/src/components/CopyPageDropdown.tsx index c3efecc..60ad106 100644 --- a/src/components/CopyPageDropdown.tsx +++ b/src/components/CopyPageDropdown.tsx @@ -327,10 +327,23 @@ export default function CopyPageDropdown(props: CopyPageDropdownProps) { const handleOpenInAI = async (service: AIService) => { // Use raw markdown URL for better AI parsing if (service.buildUrlFromRawMarkdown) { - // Build raw markdown URL from page URL and slug - const origin = new URL(props.url).origin; - const rawMarkdownUrl = `${origin}/raw/${props.slug}.md`; + // Build absolute raw markdown URL using current origin (not props.url) + // This ensures correct URL even if props.url points to canonical/deploy preview domain + const rawMarkdownUrl = new URL( + `/raw/${props.slug}.md`, + window.location.origin, + ).toString(); const targetUrl = service.buildUrlFromRawMarkdown(rawMarkdownUrl); + + // For ChatGPT, add fallback if URL fetch fails + if (service.id === "chatgpt") { + // Open ChatGPT with raw URL + window.open(targetUrl, "_blank"); + setIsOpen(false); + // Optional: Could add error handling here if needed + return; + } + window.open(targetUrl, "_blank"); setIsOpen(false); return; @@ -511,7 +524,12 @@ export default function CopyPageDropdown(props: CopyPageDropdownProps) {