Skip to content

Dev Mode layout builds (manual)

This is the hands-on layout workflow used in the duda content/layout repo (the projects/<name>/ folders driven by the shared CLAUDE.md SOP). It is separate from the MCP/API flows: use this when you are pouring approved copy into a Duda flex or classic-grid page by editing Dev Mode HTML directly, not creating pages through create_page_draft (Pages v2) or content injection.

Video tutorial coming soon — placeholder reserved above.

  • The page already exists and you are replacing its content on the SOP layout (e.g. a service page or city page rebuild).
  • You need pixel control that the editor alone is slow at: edit specific widgets by id, regenerate tables, rewrite location links, fix CSS by section.
  • The source platform is white-label Duda (seonavigator.dudasitebuilder.com).

For brand-new pages or simple section inserts, prefer the API flows linked above.

  1. Every change to a live site needs the client/owner’s approval first. Never apply to Duda on your own.
  2. Only operate on the project’s own site IDscripts/duda-lib.js has a guard; never touch another site.
  3. Edit existing pages in place (HTML replace, URL/SEO preserved) or a duplicated -new staging page — decide per task and state which.
  4. Secrets (.env, .duda-session/, session-info.json) are never committed (already gitignored).
projects/<name>/
README.md # site ID, page IDs, content links, status
content/ # source doc (.md/.html) + cleaned copy
scripts/ # duda-lib.js (site-ID guard), build-<page>.js, inspect-*.js, qa-pages.js
source/devmode/<page>/ # exported Dev Mode files + the built <page>.NEW.html
screenshots/ # QA images (gitignored)
TEST-SCENARIOS.md # what the QA suite checks
  1. Prepare inputs. Export the content doc to content/ (md/html), preserving tag structure (h1/h2/p/table). Strip embedded base64 images into a .clean.md.
  2. Pick the target. Either replace the existing page’s Dev Mode HTML in place (preferred — keeps URL/SEO) or duplicate to a -new staging page first.
  3. Export Dev Mode files for the page into source/devmode/<page>/: <page>.html (this doubles as your rollback copy), plus the CSS files.
  4. Inspect structure: node scripts/inspect-page.js <page>/<page>.html (flex) or node scripts/inspect-grid.js (classic grid) → map section id → widget id/type/text.
  5. Map content → sections. Follow the doc: keep / update / drop; surplus info goes to the FAQ. Ask the owner on significant layout calls.
  6. Build <page>.NEW.html with a build-<page>.js script: load the Dev Mode HTML in headless Chromium, edit in place by widget id (keep ids/classes/CSS, never replace a whole section’s innerHTML). Tables: generate the data-ext base64 (dmTable renders from data-ext, not raw <table>). Check <div> balance.
  7. Paste the NEW HTML into Dev Mode (owner does this), Save → get the preview link. If Duda rejects the structure, paste back <page>.html to restore.
  8. Run the QA suite (next section) against the preview link.
  9. Fix layout/CSS in the Dev Mode CSS, bound to the stable numeric section id ([id="123456"] ...), not the hex flex-id.
  10. FAQ + meta titles in the visual editor (accordions live in the Duda model, not in HTML).
  11. Go live (with approval): publish the page (HTML was replaced in place), or slug-swap a -new dup. URL/SEO preserved either way.
  12. Handover in ClickUp — plain text, no emoji, bare URLs (see the comment template in the repo CLAUDE.md).

The repo ships an automated suite — run it against the rendered preview, never just grep the file:

Terminal window
cd projects/<name>
node scripts/qa-pages.js

It checks, per page: HTTP 200; every H1/H2/H3 from the built .NEW.html present in the live DOM (matched against tag-stripped raw HTML, immune to entrance-animation hidden state); contrast candidates (heuristic — confirm by screenshot); dmTable rows/cells; responsive on desktop 1280, tablet 820, and a real mobile UA (fresh load — a resized viewport gives a false Duda overflow); plus any page-specific regression guards. Scenarios are documented in projects/<name>/TEST-SCENARIOS.md.

  • dmTable cell color: fix with page CSS [id="TABLE_ID"] td.cell{color:#2c2c2c !important;}, NOT inline <td style> — dmTable regenerates the table from data-ext and drops inline styles.
  • fullBleed backgrounds live in the Duda model, not in Dev Mode CSS/HTML, and the rendered background varies per page. Measure the real rendered bg in QA, then set white-on-dark / dark-on-light. Forcing dark uniformly causes dark-on-dark — a real failure.
  • FAQ is usually a custom_extension accordion widget (not raw HTML). Edit Q&A in the editor; don’t add a duplicate static FAQ. Watch for template residue (wrong city names).
  • Contrast scans must account for background-image/gradients and skip buttons/badges — a color-only check flags white-on-dark sections as false positives. Confirm with a screenshot.
  • Stuck Duda “Reviews” app: the native Reviews custom_extension can spin forever with no data — and this is often site-wide (broken on the live page too), not a build defect. It cannot be fixed in Dev Mode code (data lives in the app). Workaround: replace it with a working review embed (e.g. the reputationhub review iframe used elsewhere on the site).
  • Mobile QA: open a fresh context with a phone user-agent and load from scratch; do not just resize, or Duda keeps the tablet container (.dmInner{min-width:768px}) and shows a false overflow.

Duda blog posts are edited in the Blog editor, not Dev Mode. Build a clean, browser-renderable *.BLOG.html (headings, lists, tables, links — no base64), open it in a browser, copy all, and paste into the post body. Set title, slug, meta, category, author, and the featured/banner image as separate blog fields — they are not part of the pasted body. (For the API-driven blog flow instead, see Blog posts.)

The build scripts, per-project folders, and QA suite described here live in the supportsn/duda repo (projects/<name>/ + the shared CLAUDE.md at the repo root).