fix: add xmlns to AbacusStatic for Typst SVG parsing
- Add xmlns="http://www.w3.org/2000/svg" to AbacusStatic root svg element - Fixes "failed to parse SVG (missing root node)" Typst error - React's renderToStaticMarkup doesn't add xmlns by default - Required for standalone SVG files used outside HTML context - Added debug logging to calendar generation route Root cause: Typst's SVG parser requires explicit XML namespace declaration. React assumes SVGs are embedded in HTML where xmlns is optional. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -37,20 +37,44 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
// Generate day SVGs (1 to maxDay)
|
||||
for (let day = 1; day <= maxDay; day++) {
|
||||
const svg = execSync(`npx tsx "${scriptPath}" ${day} 2`, {
|
||||
encoding: 'utf-8',
|
||||
cwd: process.cwd(),
|
||||
})
|
||||
writeFileSync(join(tempDir, `day-${day}.svg`), svg)
|
||||
try {
|
||||
const svg = execSync(`npx tsx "${scriptPath}" ${day} 2`, {
|
||||
encoding: 'utf-8',
|
||||
cwd: process.cwd(),
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
})
|
||||
if (!svg || svg.trim().length === 0) {
|
||||
console.error(`Empty SVG for day ${day}`)
|
||||
throw new Error(`Generated empty SVG for day ${day}`)
|
||||
}
|
||||
writeFileSync(join(tempDir, `day-${day}.svg`), svg)
|
||||
} catch (error: any) {
|
||||
console.error(`Error generating day ${day} SVG:`, error.stderr || error.message)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// Generate year SVG
|
||||
const yearColumns = Math.max(1, Math.ceil(Math.log10(year + 1)))
|
||||
const yearSvg = execSync(`npx tsx "${scriptPath}" ${year} ${yearColumns}`, {
|
||||
encoding: 'utf-8',
|
||||
cwd: process.cwd(),
|
||||
})
|
||||
writeFileSync(join(tempDir, 'year.svg'), yearSvg)
|
||||
try {
|
||||
const yearSvg = execSync(`npx tsx "${scriptPath}" ${year} ${yearColumns}`, {
|
||||
encoding: 'utf-8',
|
||||
cwd: process.cwd(),
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
})
|
||||
console.log(`Year SVG length: ${yearSvg.length}, starts with: ${yearSvg.substring(0, 100)}`)
|
||||
if (!yearSvg || yearSvg.trim().length === 0) {
|
||||
console.error(`Empty SVG for year ${year}`)
|
||||
throw new Error(`Generated empty SVG for year ${year}`)
|
||||
}
|
||||
writeFileSync(join(tempDir, 'year.svg'), yearSvg)
|
||||
// Debug: also save to /tmp for inspection
|
||||
writeFileSync('/tmp/debug-year.svg', yearSvg)
|
||||
console.log('Saved debug year.svg to /tmp/debug-year.svg')
|
||||
} catch (error: any) {
|
||||
console.error(`Error generating year ${year} SVG:`, error.stderr || error.message)
|
||||
throw error
|
||||
}
|
||||
|
||||
// Generate Typst document
|
||||
const typstContent =
|
||||
|
||||
@@ -205,6 +205,7 @@ export function AbacusStatic({
|
||||
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={width * scaleFactor}
|
||||
height={height * scaleFactor}
|
||||
viewBox={`0 0 ${width} ${height}`}
|
||||
|
||||
Reference in New Issue
Block a user