4b36ce0d6aa2eab4870bb14020a5aa3b1c8b9af2
Editing the Header/Footer sets activePageId to '__header__'/'__footer__', which matches no entry in `pages`. save() was serializing the live canvas into the top-level page slots (mislabeled as page content, matching no page) while exporting header/footer from stale stored state — auto-save every 30s silently dropped header/footer edits. Extract buildSavePayload() as a pure, unit-tested helper: header/footer craft state now comes from the live canvas when that zone is being edited (else stored state), and the top-level page fields fall back to the landing page's stored state when a header/footer zone is active, so page content is never clobbered or mislabeled. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Description
Visual drag-and-drop website builder using GrapesJS
Languages
TypeScript
61.2%
HTML
17.1%
JavaScript
17%
CSS
3.6%
PHP
0.8%
Other
0.3%