feat: SvelteKit integration (aeo.js/sveltekit)#64
Conversation
aeo.js/sveltekit follows the Angular plugin pattern: postBuild() scans the build output (adapter-static's build/, or .svelte-kit/output for other adapters' prerendered pages), generates all AEO files alongside it, and injects the widget into every prerendered page. generate() discovers routes from src/routes (group segments transparent, dynamic segments skipped) and writes into static/ for dev use. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Docs PreviewPreview URL: https://feat-sveltekit-plugin.aeojs.pages.dev This preview was deployed from the latest commit on this PR. |
Greptile SummaryAdds the
Confidence Score: 5/5Safe to merge — the new integration is well-tested with real-filesystem fixtures and all previously reported correctness issues have been addressed. The plugin is a net-new entry point that doesn't touch any shared runtime paths. All four previously flagged correctness issues are fixed and covered by new tests. The one remaining finding is a minor inconsistency in src/plugins/sveltekit.ts — the title/description fallback ordering in Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
subgraph postBuild["postBuild(config)"]
PD[detectSvelteKitOutputDir] --> PS[scanHtmlOutput - build/ or client/]
PS --> PP[scanHtmlOutput - prerendered/pages]
PP --> PSR[scanSvelteKitRoutes - src/routes]
PSR --> PM["Merge: discovered > source > config.pages wins"]
PM --> PF[Apply config.title/description fallbacks]
PF --> PG[generateAEOFiles → outDir]
PG --> PI{injectWidget?}
PI -->|yes| PW[injectWidgetIntoHtml outDir + prerenderedDir]
PI -->|no| PE[done]
PW --> PE
end
subgraph generate["generate(config)"]
GS[scanSvelteKitRoutes - src/routes] --> GM["Build pageMap: discovered, then config.pages wins"]
GM --> GF["Apply config.title/description fallbacks before override"]
GF --> GG[generateAEOFiles → static/]
end
subgraph getWidgetScript["getWidgetScript(config)"]
WR[resolveConfig] --> WE{widget.enabled?}
WE -->|no| WN[return empty string]
WE -->|yes| WJ["JSON.stringify + escape < > &"]
WJ --> WT[return script tag]
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
subgraph postBuild["postBuild(config)"]
PD[detectSvelteKitOutputDir] --> PS[scanHtmlOutput - build/ or client/]
PS --> PP[scanHtmlOutput - prerendered/pages]
PP --> PSR[scanSvelteKitRoutes - src/routes]
PSR --> PM["Merge: discovered > source > config.pages wins"]
PM --> PF[Apply config.title/description fallbacks]
PF --> PG[generateAEOFiles → outDir]
PG --> PI{injectWidget?}
PI -->|yes| PW[injectWidgetIntoHtml outDir + prerenderedDir]
PI -->|no| PE[done]
PW --> PE
end
subgraph generate["generate(config)"]
GS[scanSvelteKitRoutes - src/routes] --> GM["Build pageMap: discovered, then config.pages wins"]
GM --> GF["Apply config.title/description fallbacks before override"]
GF --> GG[generateAEOFiles → static/]
end
subgraph getWidgetScript["getWidgetScript(config)"]
WR[resolveConfig] --> WE{widget.enabled?}
WE -->|no| WN[return empty string]
WE -->|yes| WJ["JSON.stringify + escape < > &"]
WJ --> WT[return script tag]
end
Reviews (7): Last reviewed commit: "fix(sveltekit): warn when output directo..." | Re-trigger Greptile |
…script tag escaping - Widget injection for non-static adapters now scans .svelte-kit/output/prerendered/pages (not just the client dir which holds only JS/CSS bundles) - config.pages entries now take highest merge priority — they always overwrite auto-discovered pages with the same pathname instead of being silently dropped - JSON config serialized into the <script> block now escapes <, >, and & as unicode escapes to prevent </script> in config values from prematurely closing the script element Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@greptileai review |
|
@greptileai review |
…rate() pages
- Replace outputDir.includes('.svelte-kit') with existsSync(prerenderedDir) so
the non-static adapter path works even when the caller sets a custom outDir.
- Apply Map-based deduplication in generate() so config.pages always wins over
auto-scanned routes, matching the postBuild() merge behaviour.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@greptileai review |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@greptile review |
Adds the SvelteKit plugin — the types and detection already anticipated it (
FrameworkTypeincludessveltekit, tsup externals include@sveltejs/kit); this ships the actual integration.What
aeo.js/sveltekitnew entry point following the Angular plugin pattern:postBuild()— detects the output dir (build/for adapter-static,.svelte-kit/output+ prerendered pages for other adapters), scans prerendered HTML for content, generates all AEO files alongside the build, and injects the Human/AI widget into every prerendered page (idempotent, opt-out viainjectWidget: false).generate()— source-only mode scanningsrc/routes(+page.svelte/+page.md/+page.svx; route groups(name)transparent, dynamic[slug]segments skipped), writing intostatic/.getWidgetScript()— same surface as the Angular plugin.exportsmap wiringframeworks/sveltekitguide + sidebar entry + README quick start & table rowVerification
tsc --noEmitclean, build succeeds with the new entry🤖 Generated with Claude Code