page-faq

star 0

Use when the operator wants a full client FAQ page assembled end-to-end from origin content. This is the Tier-3 composing skill - it invokes origin-scrape-faq, renders markdown via `src/lib/faq-markdown.ts`, writes the client's `lib/faqs.ts`, wires `FaqPage.astro` with shared `faq-block.css` + SectionBackdrop, and fires a preview build via build-trigger. Natural prompts include "build the FAQ page for revibetherapy.com", "let's do the FAQs for <client>", "stage 5c FAQ for <slug>", "the origin FAQ changed - rebuild ours from it", "regenerate the FAQ page", or any phrase where the user wants a whole-page FAQ pipeline kicked off (not a single edit). DO NOT use for: adding or editing one FAQ item (just edit `lib/faqs.ts` directly - much faster), styling tweaks on the FAQ accordion (edit `src/styles/faq-block.css`), changing accordion JS behavior (lives in `revibe-therapy/layouts/RevibeLayout.astro` for now, will move to shared layout next), or copy reviews of existing FAQ content.

Moonraker-AI By Moonraker-AI schedule Updated 6/8/2026

name: page-faq description: Use when the operator wants a full client FAQ page assembled end-to-end from origin content. This is the Tier-3 composing skill - it invokes origin-scrape-faq, renders markdown via src/lib/faq-markdown.ts, writes the client's lib/faqs.ts, wires FaqPage.astro with shared faq-block.css + SectionBackdrop, and fires a preview build via build-trigger. Natural prompts include "build the FAQ page for revibetherapy.com", "let's do the FAQs for ", "stage 5c FAQ for ", "the origin FAQ changed - rebuild ours from it", "regenerate the FAQ page", or any phrase where the user wants a whole-page FAQ pipeline kicked off (not a single edit). ALSO covers service-page FAQs: "do the service pages have FAQs", "add FAQs + FAQPage schema to the service pages", "the service pages are missing FAQ schema" (see Service-page mode section). DO NOT use for: adding or editing one FAQ item (just edit lib/faqs.ts directly - much faster), styling tweaks on the FAQ accordion (edit src/styles/faq-block.css), changing accordion JS behavior (lives in revibe-therapy/layouts/RevibeLayout.astro for now, will move to shared layout next), or copy reviews of existing FAQ content. allowed-tools: [Skill, Bash, Read, Write, Edit]

page-faq

Tier-3 composition skill. Owns the full path from "origin has FAQs" to "preview site shows FAQs". Calls four other skills + the renderFaqMarkdown helper.

When to use

  • A new client migration is at stage 5c (About + Contact) and the FAQ page is one of the artifacts.
  • Origin's /faqs/ content has changed and the client wants the site refreshed.

Required inputs

  1. Site identifier - slug (e.g. revibetherapy.com) or sites.id UUID.
  2. Origin FAQ URL - full URL, e.g. https://revibetherapy.com/faqs/. If the user did not provide one, look up the site's origin_url from Supabase and try <origin>/faqs/ then <origin>/faq/ then <origin>/frequently-asked-questions/ until 200.
  3. Client folder name in moonraker-site-template/ (e.g. revibe-therapy). If the user did not provide one, resolve via the site's client_folder field or fall back to a sluggified sites.slug.

Execution

Run these steps in order. Halt on any failure and report.

  1. Scrape origin - invoke the origin-scrape-faq skill with the origin FAQ URL. Capture output path (/tmp/<host>-faqs.json).
  2. Render markdown - read the JSON. For each { q, a } pair, call renderFaqMarkdown(a) (logic lives in moonraker-site-template/src/lib/faq-markdown.ts). Output is either a string or { html, block: true } ready for FAQAccordion.
  3. Write per-client lib/faqs.ts with this shape:
    // Auto-generated from origin /faqs/ scrape on <ISO date>.
    export interface ClientFaq {
      question: string;
      answer: string | { html: string; block: true };
    }
    export const clientFaqs: ClientFaq[] = [ ... ];
    
    Use the existing per-client identifier convention if one exists (e.g. Revibe uses revibeFaqs + RevibeFaq). Don't invent a new name if a precedent exists in the folder.
  4. Wire FaqPage.astro in <client>/templates/FaqPage.astro to:
    • Import '../../src/styles/faq-block.css' at top of frontmatter.
    • Import FAQAccordion from per-client components.
    • Import SectionBackdrop from ../../src/components/SectionBackdrop.astro.
    • Wrap <FAQAccordion faqs={clientFaqs} /> in <SectionBackdrop> with the client's hero image.
    • Emit JSON-LD FAQPage schema from the faqs (plain text only).
    • Bottom CtaSection optional but recommended.
  5. Astro build smoke - run npx --no-install astro build from moonraker-site-template/ root. Halt on any error.
  6. Commit + push - confirm with the operator before pushing. Use a commit message like:
    <client>: FAQ page from origin scrape (<n> Q+A)
    
  7. Trigger build - invoke the build-trigger skill with the site's slug, --target preview, --reason migration_complete. Suggest --wait so the operator knows when staging reflects the change.
  8. Final URL - report https://sites.moonraker.ai/<slug>/faq/ for verification.

Output format

FAQ page built end-to-end
  client: <slug>
  origin: <FAQ URL>
  faqs: <n>
  lib: <client>/lib/faqs.ts
  template: <client>/templates/FaqPage.astro
  build: <build_id>  staging: https://sites.moonraker.ai/<slug>/faq/

Service-page mode (FAQs on service pages, not the standalone FAQ page)

Proven 2026-06-11 on ITR (11 service pages) and Revibe (4 EN + 4 ES). Requirement: every service page carries a visible FAQ section AND exactly ONE FAQPage JSON-LD node, with every schema question also visible on-page (Google rich-results requirement).

Two situations, two paths:

  1. FAQ content does not exist yet (the ITR case): author 5-6 Q&As per service grounded STRICTLY in that page's existing copy (overview, science, phases, fit, benefits). No invented clinical claims, no pricing numbers not already in the content, no outcome guarantees. Store as a faq field on the per-client service content ({ eyebrow, title, items: [{ question, answer }] }, the aoth/itr shape), then render via the shared bespoke-shared/components/ServiceFaq.astro, which emits the FAQPage JSON-LD itself. Do not build a new component.
  2. FAQ content exists but schema is missing (the Revibe case: a UI-only accordion like FAQAccordion): leave the accordion untouched and build the FAQPage node in the service template frontmatter from the same faqs data, merged into the layout's schema array. Strip answers to plain text for JSON-LD (HTML tags, markdown links and emphasis), and guard against a second FAQPage node already present in the incoming schema array.

Origin scrape first: probe the live/origin service pages for existing FAQ content before authoring. Carry faithfully if found.

Local smoke for bespoke templates (no DB payload needed)

npx astro build from the repo root does NOT compile bespoke client templates: they only enter the build when materialize writes wrapper pages from the DB payload, which is VPS-only. To smoke a template change locally, write temporary wrapper pages under src/pages/zz-smoke/ that import the templates directly (mimic the materialized shape, e.g. <ServicePage slug={'/emdr-therapy/'} />, or a [slug].astro with getStaticPaths over all services), build, assert on dist/zz-smoke/ HTML (one FAQPage node per page, schema questions present in visible markup), then DELETE the smoke dir before committing.

GOTCHA: do NOT name the smoke dir _smoke. Astro silently excludes underscore-prefixed files/dirs under src/pages/ from routing: the build "succeeds" while building none of your smoke pages. Use a non-underscore name like zz-smoke.

Bugs to skip (encoded in shared lib + CSS; do not duplicate)

  • The 8 bugs from playbooks/site-migration-base.md Stage 5c apply here. Do not re-introduce per-page CSS for FAQ padding, specificity collisions, or list-marker alignment - they live in src/styles/faq-block.css once.
  • Generator must use renderFaqMarkdown from src/lib/faq-markdown.ts. Do NOT regex ^\d+\.\s+\*\* to detect lists; the helper handles blank-line-tolerant list grouping.
  • The materialize pipeline pulls published_meta from site_pages - if title/desc don't match what the template's resolvedMeta says, update the DB row (do NOT change the template's spread order).

Boundaries

  • Do not write FAQ content that wasn't on the origin. If a Q+A pair needs to be edited, surface that and let the operator confirm.
  • Do not change FAQAccordion styling - only wire and pass data.
  • Do not push to a per-client repo - moonraker-site-template is the only repo. Per-client folders live as siblings under src/ and <client>/.
Install via CLI
npx skills add https://github.com/Moonraker-AI/moonraker-agent --skill page-faq
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
Moonraker-AI
Moonraker-AI Explore all skills →