649 lines
23 KiB
Markdown
649 lines
23 KiB
Markdown
# Arizona Institute for Autism Astro Site
|
|
|
|
Static Astro + TypeScript migration of the public Arizona Institute for Autism
|
|
website.
|
|
|
|
## Quick Start
|
|
|
|
Run commands from this directory:
|
|
|
|
```sh
|
|
cd www
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
Astro prints the local development URL, normally:
|
|
|
|
```txt
|
|
http://localhost:4321
|
|
```
|
|
|
|
The development server watches source files and refreshes the browser after
|
|
edits. Stop it with `Ctrl+C`.
|
|
|
|
## Environment Setup
|
|
|
|
Requirements:
|
|
|
|
- Node.js 22.12 or newer (see `package.json`); the Nix shell supplies Node.js 24
|
|
- npm
|
|
|
|
This repository also has a Nix development shell at the repository root:
|
|
|
|
```sh
|
|
cd ..
|
|
nix --extra-experimental-features "nix-command flakes" develop
|
|
cd www
|
|
npm install
|
|
```
|
|
|
|
### Local Playwright environment (Linux)
|
|
|
|
From the repository root, enter the opt-in browser shell:
|
|
|
|
```sh
|
|
nix --extra-experimental-features "nix-command flakes" develop .#browser
|
|
cd www
|
|
TMPDIR=/tmp npm run build
|
|
TMPDIR=/tmp node tools/playwright-smoke.mjs
|
|
```
|
|
|
|
The existing `flake.lock` pairs the Nix Playwright driver and Chromium/headless
|
|
shell. `PLAYWRIGHT_MODULE` points directly to that driver; `PLAYWRIGHT_BROWSERS_PATH`
|
|
selects its matching browsers. Fontconfig supplies Latin/Arabic fallback fonts.
|
|
The ordinary development shell and npm dependencies remain unchanged. This
|
|
browser shell is offered on Linux; the existing Darwin development shell is
|
|
unchanged. Do not run `npx playwright install` or mix an unrelated npm Playwright
|
|
version with these browser revisions.
|
|
|
|
The smoke test starts Astro preview and Chromium in the **same execution** on an
|
|
ephemeral `127.0.0.1` port. It blocks external and non-GET/HEAD requests, loads the
|
|
real Spanish privacy and Library pages, verifies staging robots/title/H1, captures
|
|
two full-page screenshots in a new `/tmp/aia-playwright-smoke-*` directory, and
|
|
closes browser/preview. It does not submit forms or exercise production APIs.
|
|
Success establishes browser transport only, not Phase 8 visual or human acceptance.
|
|
|
|
Use the [Phase 8 guarded browser procedure](reports/phase-8-host-browser-verification-2026-10-14.md)
|
|
for full review. Entering the Nix shell does not repair an already-running remote
|
|
MCP transport or relax sandbox permissions. If the autonomous environment cannot
|
|
access the Nix store, trusted certificates, sockets or browser runtime files, run
|
|
the same smoke test from the host terminal. Do not disable TLS verification or
|
|
bypass the sandbox. The Nix environment needs host validation before browser
|
|
availability can be claimed.
|
|
|
|
Copy the example environment file when testing the like/view counter or staging
|
|
SEO behavior:
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
```
|
|
|
|
The default values are:
|
|
|
|
```txt
|
|
PUBLIC_AIA_API_BASE=https://api.azinstitute4autism.com
|
|
PUBLIC_ALLOW_INDEXING=false
|
|
```
|
|
|
|
The site still renders when the AIA API is unavailable. Migration and staging
|
|
builds emit `noindex,nofollow` by default. `PUBLIC_ALLOW_INDEXING=true` enables
|
|
production publication policy, including per-page noindex exceptions. Exercise
|
|
that mode locally with `PUBLIC_ALLOW_INDEXING=true npm run build`; this does
|
|
not deploy anything or change environment files. Run `npm run build` afterward
|
|
to restore staging output. Only explicitly authorized production deployments
|
|
should publish indexing-enabled artifacts.
|
|
|
|
## View And Build
|
|
|
|
### Development Server
|
|
|
|
Use this while editing:
|
|
|
|
```sh
|
|
npm run dev
|
|
```
|
|
|
|
Useful development URLs include:
|
|
|
|
```txt
|
|
/
|
|
/aba-therapy
|
|
/autism-evaluations
|
|
/learner-social-club
|
|
/client-consultation
|
|
/library
|
|
/es
|
|
/es/library
|
|
/ar/library
|
|
```
|
|
|
|
### Static Build
|
|
|
|
Generate the static site with staging indexing protection:
|
|
|
|
```sh
|
|
npm run build
|
|
```
|
|
|
|
The autonomous Codex sandbox denies `/etc/hosts`, so its Node runtime cannot
|
|
resolve `localhost`. Use this equivalent validation command only inside that
|
|
sandbox:
|
|
|
|
```sh
|
|
npm run build:sandbox
|
|
```
|
|
|
|
Build output is written to:
|
|
|
|
```txt
|
|
dist/
|
|
```
|
|
|
|
### Preview Production Output
|
|
|
|
After a successful build:
|
|
|
|
```sh
|
|
npm run preview
|
|
```
|
|
|
|
Astro prints the preview URL, normally `http://localhost:4321`.
|
|
|
|
### Validate Before Committing
|
|
|
|
```sh
|
|
npm run build
|
|
npm run audit:links
|
|
npm run audit:images
|
|
npm run audit:blog
|
|
```
|
|
|
|
The link audit reads `dist/` after a successful build. If rendered output is
|
|
unavailable, it audits generated source routes, relative and root-relative
|
|
Markdown links, and public assets instead. It writes:
|
|
|
|
```txt
|
|
reports/broken-links.md
|
|
```
|
|
|
|
## Editing Content
|
|
|
|
Normal content editing happens in Markdown:
|
|
|
|
```txt
|
|
src/content/pages/en
|
|
src/content/pages/es
|
|
src/content/pages/ar
|
|
src/content/blog/en
|
|
src/content/blog/es
|
|
src/content/blog/ar
|
|
src/content/authors/en
|
|
src/content/authors/es
|
|
src/content/authors/ar
|
|
```
|
|
|
|
Page and post frontmatter is validated by `src/content.config.ts`.
|
|
|
|
Example:
|
|
|
|
```md
|
|
---
|
|
title: "Example Article"
|
|
description: "Short search and social description."
|
|
slug: "example-article"
|
|
canonical: "https://www.azinstitute4autism.com/library/example-article"
|
|
lang: "en"
|
|
translationKey: "example-article"
|
|
featuredImage: "/assets/images/example.webp"
|
|
alt: "Descriptive image alt text"
|
|
date: "2026-06-07"
|
|
author: "rula-diab"
|
|
category: "Library"
|
|
tags:
|
|
- ABA Therapy
|
|
draft: false
|
|
---
|
|
|
|
Article content goes here.
|
|
```
|
|
|
|
Set `draft: true` while preparing unpublished content.
|
|
|
|
### Display Headings and Social Metadata
|
|
|
|
Pages and articles may supply an optional plain-text `displayH1` in frontmatter:
|
|
|
|
```yaml
|
|
title: "The existing SEO title"
|
|
displayH1: "The source-supported visible heading"
|
|
```
|
|
|
|
The override changes only the visible H1. It does not change the document or
|
|
social title, article cards, navigation labels, or related-post text. Empty,
|
|
whitespace-only and non-string overrides fail content validation. Without an
|
|
override, articles keep `title`, regular pages keep their existing service/page
|
|
heading mappings and title-derived fallback, and homepage/Library components
|
|
keep their existing headings. Homepage heading markup stays intact unless a
|
|
plain-text override is explicitly supplied. Library template SEO titles remain
|
|
unchanged. Front Matter CMS exposes the optional field for pages and blog posts.
|
|
|
|
Existing featured images and page banner fallbacks supply `og:image` and
|
|
`twitter:image`. Relative paths resolve against the public origin in
|
|
`src/data/site.json`, never a preview host or an external canonical. Existing
|
|
`alt` text supplies both image-alt metadata tags only when it describes the
|
|
selected featured image; no descriptions are invented for banner fallbacks.
|
|
Pages without a selected image omit image tags and retain the `summary` card;
|
|
image pages retain `summary_large_image`.
|
|
|
|
`og:locale` is omitted: the content languages `en`, `es` and `ar` do not establish
|
|
the regional `language_TERRITORY` values required by the
|
|
[Open Graph protocol](https://ogp.me/). Regional targeting remains a human
|
|
localization decision. HTML language/direction and hreflang are unchanged.
|
|
|
|
Run `npm run test:seo` for isolated real-Astro builds covering heading defaults,
|
|
overrides, schema rejection, image metadata and shared publication invariants
|
|
in staging and indexing modes. Fixtures never modify the working content or
|
|
the project's `dist/`. See the dated Phase 4A section of
|
|
[`reports/migration-summary.md`](reports/migration-summary.md) for source evidence.
|
|
|
|
### Publication, Canonicals, and Sitemap
|
|
|
|
`src/utils/publication-policy.ts` owns route eligibility, normalized public
|
|
URLs, canonical validation, robots values, and sitemap eligibility.
|
|
`src/utils/publication.ts` loads the Astro collections into that manifest.
|
|
`src/pages/[...slug].astro` generates every content route from eligible entries,
|
|
including home and Library indexes; their existing presentation components are
|
|
under `src/components/pages/`. Shared SEO and the generated sitemap use that
|
|
same manifest. The route and source-link audits also reuse the policy.
|
|
|
|
- `draft: true` means unpublished: no generated HTML route in either build mode.
|
|
The Arabic homepage `/ar` remains a draft; published Arabic Library routes
|
|
remain available. Navigation does not link to the unpublished homepage.
|
|
- `noindex: true` keeps a published route accessible, emits `noindex,follow`
|
|
in indexing-enabled builds, and excludes it from the sitemap. It defaults
|
|
to `false`. Staging always overrides this with `noindex,nofollow`.
|
|
- An omitted `canonical` gets the normalized public URL from `site.json` and
|
|
its local route. A supplied local canonical must match that route. Invalid
|
|
canonicals, duplicate canonical targets, and route collisions fail validation.
|
|
- Verified syndicated articles use their existing `canonical` field for the
|
|
external publisher URL. External-canonical routes are excluded from the
|
|
sitemap even when they are not marked noindex. Do not use canonical values
|
|
to create local routes or sitemap locations.
|
|
- `src/pages/sitemap.xml.ts` generates `dist/sitemap.xml` on every build.
|
|
Staging emits an empty sitemap and does not advertise it in `robots.txt`.
|
|
Indexing-enabled builds include only eligible, indexable, self-canonical
|
|
local routes. There is no hand-maintained `public/sitemap.xml`.
|
|
- `npm run generate:sitemap` is a compatibility command that runs the Astro
|
|
build; it no longer writes a separate public sitemap from frontmatter strings.
|
|
|
|
The verified noindex exceptions are `/schedule-consultation`, `/employee-portal`,
|
|
`/library/community-highlight-meet-rula-diab`, and
|
|
`/library/new-aia-scottsdale-office`. The last two also retain their verified
|
|
external canonicals. The dated evidence is in `reports/migration-summary.md`.
|
|
|
|
Run `npm run test:publication` for policy tests and isolated builds of the
|
|
actual application in staging and indexing-enabled modes. Fixtures test draft
|
|
content, draft home/Library indexes, missing and external canonicals, and
|
|
generated head/sitemap consistency without modifying the working site's output.
|
|
The policy is TypeScript; Node audit/test commands use `--experimental-strip-types`
|
|
for compatibility with the declared Node 22.12 minimum. Dependencies are unchanged.
|
|
|
|
After publication changes, build and run `npm run audit:routes -- --offline`
|
|
before `npm run audit:routes -- --check`. This creates a newly dated local
|
|
reconciliation using saved production observations, preserving earlier evidence.
|
|
Saved rendered metadata is specific to its build mode: after restoring the
|
|
normal staging build, reconcile that output again before checking it.
|
|
|
|
### Links And Buttons
|
|
|
|
Use normal Markdown links for links within prose:
|
|
|
|
```md
|
|
Read the [ABA therapy guide](/aba-therapy) for more information.
|
|
```
|
|
|
|
Prose links render as the live site's orange inline links. Do not place an
|
|
ordinary Markdown link on its own line merely to make it look like a button.
|
|
|
|
Use `.mdx` and the `Button` component only for a source-verified call to action:
|
|
|
|
```mdx
|
|
import Button from '../../../components/Button.astro';
|
|
|
|
<Button href="/client-consultation">Request an Appointment</Button>
|
|
<Button href="/services" variant="outlined">Explore Services</Button>
|
|
<Button href="https://example.com" target="_blank">External Action</Button>
|
|
```
|
|
|
|
Available `Button` variants are `filled` (default), `outlined`, and `light`.
|
|
Available sizes are `default` and `small`. A `_blank` target automatically adds
|
|
`rel="noopener noreferrer"`.
|
|
|
|
Normal Markdown links remain preferred for ordinary page and article content.
|
|
|
|
### Stable Heading Links
|
|
|
|
Astro automatically generates an ID for each Markdown heading. In `.md` files,
|
|
when a section needs a stable, editorially controlled fragment link, add an
|
|
explicit ID with Sätteri heading-attribute syntax:
|
|
|
|
```md
|
|
## Accepted Insurance Carriers {#accepted-insurance-heading}
|
|
```
|
|
|
|
Link to it with the resulting fragment URL:
|
|
|
|
```md
|
|
[View accepted carriers](/insurance#accepted-insurance-heading)
|
|
```
|
|
|
|
Keep explicit IDs unique within the page, lowercase, and hyphenated. Treat a
|
|
published ID as permanent so inbound links do not break when heading text is
|
|
edited. The installed MDX parser rejects this shorthand, independently of
|
|
directive parsing. In `.mdx` files, use an explicit HTML heading instead:
|
|
|
|
```mdx
|
|
<h2 id="accepted-insurance-heading">Accepted Insurance Carriers</h2>
|
|
```
|
|
|
|
### Markdown Directives
|
|
|
|
Sätteri directive parsing is disabled. The content corpus has no intentional
|
|
container (`:::name`), leaf (`::name`), or text (`:name`) directives, and no
|
|
directive transformation plugins are registered. Enabling parsing silently
|
|
removed literal text such as `:1` in `1:1`, `:00` in times, and `:Plan` after
|
|
an adjacent colon. Heading attributes remain enabled.
|
|
|
|
Run `npm run test:markdown` after changing the Markdown/MDX configuration. It
|
|
builds temporary fixtures and the affected content through the actual Astro
|
|
configuration, checking ratios, punctuation, times, URLs, code, and explicit
|
|
heading IDs. It makes no production requests and leaves no fixture routes in
|
|
the site. Any future directive feature needs compatible rendering and must
|
|
preserve these literal-content checks.
|
|
|
|
### Front Matter CMS
|
|
|
|
The project includes `frontmatter.json` for the Front Matter CMS VS Code
|
|
extension. Open the `www` folder as the editor workspace so its content folders
|
|
and media paths resolve correctly.
|
|
|
|
### Edit The Homepage
|
|
|
|
The English and Spanish homepages are driven from the structured `home:`
|
|
frontmatter block in:
|
|
|
|
```txt
|
|
src/content/pages/en/index.md
|
|
src/content/pages/es/index.md
|
|
```
|
|
|
|
`HomePage.astro` renders those named sections in order. Use the section names
|
|
as the editing surface:
|
|
|
|
```txt
|
|
hero
|
|
servicesIntro
|
|
benefits
|
|
skills
|
|
insurance
|
|
esa
|
|
hsaFsa (optional; English only where published)
|
|
financialHelp
|
|
process
|
|
director
|
|
testimonials
|
|
logos (optional)
|
|
```
|
|
|
|
Keep homepage copy in those named blocks so the page remains easy to scan in
|
|
Front Matter CMS and VS Code. `src/content.config.ts` validates the structure.
|
|
`hsaFsa` uses `heading`, `body`, `image`, and `imageAlt`; omit the whole block
|
|
where no section is published. It renders between ESA and financial help.
|
|
`logos.items` holds `file`/`alt` pairs after testimonials. Process steps accept
|
|
an optional `href`; use an existing intake route and section ID in the same
|
|
language. Steps without a destination remain plain content.
|
|
|
|
### Edit The Team Page
|
|
|
|
The English Team page uses the validated `team:` frontmatter block in
|
|
`src/content/pages/en/team.md`. That block is the single source for the intro,
|
|
ordered clinical groups, ABA care team, member names/roles/images, and careers
|
|
content. The Markdown body contains no second roster. Update the structured
|
|
frontmatter rather than hardcoding people in `TeamPage.astro`; image filenames
|
|
refer to `public/assets/images`.
|
|
|
|
### Images And Downloads
|
|
|
|
Store content-referenced assets in:
|
|
|
|
```txt
|
|
public/assets/images
|
|
public/assets/downloads
|
|
public/assets/media
|
|
```
|
|
|
|
Reference public assets from Markdown using root-relative paths:
|
|
|
|
```md
|
|

|
|
```
|
|
|
|
Use `src/assets/images` for images imported directly by Astro components and
|
|
processed by Astro.
|
|
|
|
### Components And Styling
|
|
|
|
Reusable page sections are in:
|
|
|
|
```txt
|
|
src/components
|
|
src/layouts
|
|
```
|
|
|
|
Global styles and design tokens are in:
|
|
|
|
```txt
|
|
src/styles/variables.css
|
|
src/styles/global.css
|
|
src/styles/rtl.css
|
|
```
|
|
|
|
Navigation, services, redirects, and site details are in:
|
|
|
|
```txt
|
|
src/data
|
|
```
|
|
|
|
## Adding Content
|
|
|
|
### Add An English Blog Post
|
|
|
|
1. Create `src/content/blog/en/post-slug.md`.
|
|
2. Add valid frontmatter and article Markdown.
|
|
3. Place referenced images in `public/assets/images`.
|
|
4. Run `npm run dev` and view `/library/post-slug`.
|
|
5. Run the production validation commands before committing.
|
|
|
|
### Add A Translation
|
|
|
|
Use the same nonempty `translationKey` across genuine translated entries in
|
|
the **same collection**. The key is an explicit equivalence declaration, not a
|
|
URL or an entry reference. Slugs may differ; similar slugs alone never create a
|
|
relationship. Do not change keys to manufacture translation pairs.
|
|
|
|
```txt
|
|
src/content/blog/en/post-slug.md
|
|
src/content/blog/es/post-slug.md
|
|
src/content/blog/ar/post-slug.md
|
|
```
|
|
|
|
The URLs become:
|
|
|
|
```txt
|
|
/library/post-slug
|
|
/es/library/post-slug
|
|
/ar/library/post-slug
|
|
```
|
|
|
|
Arabic routes automatically render with `lang="ar"` and `dir="rtl"`.
|
|
|
|
The shared publication manifest supplies both the language switcher and SEO
|
|
alternates. A translation set needs at least two eligible members. Drafts,
|
|
unpublished placeholders, noindex pages, and external-canonical pages do not
|
|
participate. Mark placeholders `draft: true`; `/ar` remains unpublished.
|
|
Author records have no generated routes yet and cannot participate.
|
|
|
|
One member per language per collection/key is allowed, including draft members;
|
|
duplicates and blank/whitespace-padded keys fail validation. A lone key is valid
|
|
and emits no alternate: it does not assert that a particular missing language
|
|
exists. Dangling graph references, wrong-family targets, ineligible targets,
|
|
and nonreciprocal links fail validation. The rendered-output regression checks
|
|
also fail if an alternate target has no generated HTML file.
|
|
|
|
Indexing-enabled builds emit the same absolute hreflang links on every member,
|
|
including its own language. `x-default` points to the eligible English member
|
|
only; sets without one omit it. Staging suppresses hreflang while retaining the
|
|
eligible language menu and global `noindex,nofollow`. Unpaired/excluded pages
|
|
retain their current-language label without an empty interactive menu.
|
|
|
|
Run `npm run test:publication`, `npm run build`, and
|
|
`PUBLIC_ALLOW_INDEXING=true npm run build` to validate both modes. Finish with
|
|
`npm run build` to restore staging. See `reports/migration-summary.md` for
|
|
Phase 3B's exact route sets, evidence, and route-audit refresh commands.
|
|
|
|
Do not publish unreviewed machine translations. Do not invent translations;
|
|
substantive translation changes require human language review.
|
|
|
|
### Edit A Blog FAQ
|
|
|
|
Posts with live-style FAQ sections use `.mdx` and import:
|
|
|
|
```mdx
|
|
import FAQAccordion from '../../../components/FAQAccordion.astro';
|
|
```
|
|
|
|
Edit the component's `label`, `heading`, and `items` data in the post. Keep
|
|
`answer` and `answerHtml` consistent. JSON-LD derives its answer text from the
|
|
actual visible `answerHtml` when supplied, otherwise from the rendered `answer`
|
|
fallback. Shared FAQ markup, styling, interaction, and schema generation remain
|
|
in `src/components/FAQAccordion.astro`, using `src/utils/structured-data.ts`.
|
|
|
|
The standalone FAQ page passes its rendered Markdown/MDX slot as `sourceHtml`
|
|
to the same component. Its server schema describes the direct H3 questions and
|
|
following answer nodes that the existing browser code turns into accordions.
|
|
Runtime-only sources without server content emit no invented FAQ schema. Do
|
|
not mix `items` with `sourceSelector`. Duplicate questions, multiple schema
|
|
producing accordions on one page, empty answers and conflicting canonical
|
|
props fail validation; consolidate questions into one accordion per page.
|
|
|
|
### Article and FAQ Structured Data
|
|
|
|
Article JSON-LD uses the existing SEO `title`, description, featured image,
|
|
language, `date`, optional `updatedDate`, and the exact locale/slug match in the
|
|
authors collection. Dates use calendar-day precision; article/card bylines
|
|
format that day in UTC to avoid shifting it on the build host. Missing
|
|
modification dates are omitted. Missing or ambiguous author references fail validation.
|
|
No author archive URL or publisher is invented. `displayH1` does not change
|
|
the schema headline. No new frontmatter fields are required.
|
|
|
|
BlogPosting and FAQPage emission reuse the manifest's `sitemapEligible` record
|
|
gate: drafts, noindex records and external-canonical records are excluded.
|
|
This gate is independent of the build's global indexing switch, so staging
|
|
can exercise schema while retaining its global noindex, empty sitemap and
|
|
absent hreflang. The existing site organization block remains unchanged.
|
|
|
|
These schemas describe the rendered local records; they do not certify that
|
|
older article dates or FAQ answers have been reconciled with production.
|
|
Phase 6C drift observations and validation results are recorded in
|
|
`reports/migration-summary.md`. Run `npm run test:seo` and
|
|
`npm run test:publication`, and validate both build modes before publication.
|
|
|
|
## Reports And Utilities
|
|
|
|
For the current migration checkpoint, next Codex phase, ratified decisions,
|
|
and outstanding cutover blockers, begin with the
|
|
**[living session handoff](reports/SESSION_HANDOFF.md)**. Update that short
|
|
handoff at each accepted milestone transition; detailed historical evidence
|
|
remains in `reports/migration-summary.md`.
|
|
|
|
Migration reports are stored in `reports/`.
|
|
|
|
Useful commands:
|
|
|
|
```sh
|
|
npm run crawl:live
|
|
npm run generate:sitemap
|
|
npm run generate:redirects
|
|
npm run audit:links
|
|
```
|
|
|
|
The live crawl is optional and may fail in restricted network environments.
|
|
|
|
## Forms
|
|
|
|
As of the owner decision on 2026-10-30, `npm run dev` and `npm run build`
|
|
use live Jotform Form A on exactly 16 approved placements: 10 immediate frames
|
|
and six deferred bilingual service drawers. No Form A flags are required.
|
|
Public development-host forms are owner-authorized. This does not authorize cutover.
|
|
|
|
Use `PUBLIC_AIA_FORMS_MODE=off npm run build` for an offline artifact, or
|
|
`PUBLIC_AIA_FORMS_MODE=mock npm run dev` for synthetic fixtures. Missing/empty
|
|
mode means live; obsolete `isolated-test` and other invalid values produce an
|
|
explicit configuration error. Remove old approval/environment variables from
|
|
local settings. Indexing is independent of forms; counters remain off by default.
|
|
|
|
See the [current Form A guide](integrations/jotform/README.md) for the exact
|
|
registry, safeguards, rollback and owner acceptance requirements. Form C remains
|
|
inactive. Employee-portal private input retains its own separate gates.
|
|
|
|
Verify matching output with
|
|
`node tools/phase10-artifact-verify.mjs --mode=staging --forms=live`;
|
|
use `--mode=indexing` for indexing output and `--forms=off` or `--forms=mock`
|
|
for those explicit builds. No actual submissions run in automated tests.
|
|
|
|
### Google Ads consultation-form conversion handoff
|
|
|
|
The Google Ads conversion ID, label, and privacy-gated Astro integration
|
|
instructions are in
|
|
[`reports/google-ads-consultation-conversion.md`](reports/google-ads-consultation-conversion.md).
|
|
This is documentation only: **do not install Google tags or conversion snippets**
|
|
on health-service pages or turn on enhanced conversions until AIA's
|
|
privacy/HIPAA and advertising-policy review explicitly approves the complete
|
|
data flow. Any future measurement needs separately approved success and privacy semantics; the former API-success premise is historical and no tracking is active.
|
|
|
|
## Troubleshooting
|
|
|
|
### `astro: command not found`
|
|
|
|
Dependencies are not installed:
|
|
|
|
```sh
|
|
npm install
|
|
```
|
|
|
|
### npm TLS or certificate errors
|
|
|
|
Do not disable npm certificate verification. Run `npm install` from a normal
|
|
host terminal or trusted development environment with working CA certificates.
|
|
|
|
### Link audit says build output is unavailable
|
|
|
|
Build first:
|
|
|
|
```sh
|
|
npm run build
|
|
npm run audit:links
|
|
npm run audit:images
|
|
npm run audit:blog
|
|
```
|
|
|
|
### A content page is missing
|
|
|
|
Check:
|
|
|
|
- its Markdown file is in the correct language/content folder
|
|
- `draft` is `false`
|
|
- `slug` is unique within that language and content type
|
|
- frontmatter satisfies `src/content.config.ts`
|