Skip to content

Commit 2fdd374

Browse files
dshkolclaude
andcommitted
Fix Safari CSS loading with post-build path conversion
- Create scripts/fix-paths.js to convert relative asset paths to absolute - Handles ./ and ../ style relative paths in href, src, and import statements - Remove broken <base> tag approach that fixed CSS but broke navigation - Convert to ES modules to match project config 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 213c6ea commit 2fdd374

3 files changed

Lines changed: 72 additions & 4 deletions

File tree

observablehq.config.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ export default {
77
// Base path for subdirectory deployment (dshkol.com/thedaily)
88
base: "/thedaily",
99

10-
// Add base tag for Safari compatibility with proxied deployment
11-
head: `<base href="/thedaily/">`,
12-
1310
root: "docs",
1411
output: "dist",
1512
style: "style.css",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"type": "module",
66
"scripts": {
77
"dev": "observable preview",
8-
"build": "observable build",
8+
"build": "observable build && node scripts/fix-paths.js",
99
"clean": "rm -rf dist .observablehq"
1010
},
1111
"keywords": [],

scripts/fix-paths.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Post-build script to convert relative asset paths to absolute paths.
4+
* Fixes Safari compatibility issues with proxied subdirectory deployments.
5+
*
6+
* Converts: href="./_import/..." and src="./_import/..."
7+
* To: href="/thedaily/_import/..." and src="/thedaily/_import/..."
8+
*/
9+
10+
import fs from 'fs';
11+
import path from 'path';
12+
import { fileURLToPath } from 'url';
13+
14+
const __filename = fileURLToPath(import.meta.url);
15+
const __dirname = path.dirname(__filename);
16+
17+
const DIST_DIR = path.join(__dirname, '..', 'dist');
18+
const BASE_PATH = '/thedaily';
19+
20+
function processHtmlFile(filePath) {
21+
let content = fs.readFileSync(filePath, 'utf8');
22+
let modified = false;
23+
24+
// Replace relative asset paths with absolute paths
25+
// Matches: href="./_something", href="../../_something", etc.
26+
const patterns = [
27+
// Match ./_something
28+
{ regex: /href="\.\/(_[^"]+)"/g, replacement: `href="${BASE_PATH}/$1"` },
29+
{ regex: /src="\.\/(_[^"]+)"/g, replacement: `src="${BASE_PATH}/$1"` },
30+
// Match ../_something or ../../_something etc.
31+
{ regex: /href="(?:\.\.\/)+(_[^"]+)"/g, replacement: `href="${BASE_PATH}/$1"` },
32+
{ regex: /src="(?:\.\.\/)+(_[^"]+)"/g, replacement: `src="${BASE_PATH}/$1"` },
33+
// Match JS imports: from "./_something" or from "../../_something"
34+
{ regex: /from "\.\/(_[^"]+)"/g, replacement: `from "${BASE_PATH}/$1"` },
35+
{ regex: /from "(?:\.\.\/)+(_[^"]+)"/g, replacement: `from "${BASE_PATH}/$1"` },
36+
// Match dynamic imports: import("./_something") or import("../../_something")
37+
{ regex: /import\("\.\/(_[^"]+)"\)/g, replacement: `import("${BASE_PATH}/$1")` },
38+
{ regex: /import\("(?:\.\.\/)+(_[^"]+)"\)/g, replacement: `import("${BASE_PATH}/$1")` },
39+
];
40+
41+
for (const { regex, replacement } of patterns) {
42+
const newContent = content.replace(regex, replacement);
43+
if (newContent !== content) {
44+
content = newContent;
45+
modified = true;
46+
}
47+
}
48+
49+
if (modified) {
50+
fs.writeFileSync(filePath, content);
51+
console.log(`Fixed paths in: ${path.relative(DIST_DIR, filePath)}`);
52+
}
53+
}
54+
55+
function processDirectory(dir) {
56+
const entries = fs.readdirSync(dir, { withFileTypes: true });
57+
58+
for (const entry of entries) {
59+
const fullPath = path.join(dir, entry.name);
60+
61+
if (entry.isDirectory()) {
62+
processDirectory(fullPath);
63+
} else if (entry.name.endsWith('.html')) {
64+
processHtmlFile(fullPath);
65+
}
66+
}
67+
}
68+
69+
console.log('Fixing asset paths for Safari compatibility...');
70+
processDirectory(DIST_DIR);
71+
console.log('Done!');

0 commit comments

Comments
 (0)