Architecture
The MyPhotoAI pSEO surface runs on a small number of moving parts. Each one does one job, and each one is replaceable.
The flow
- A slug manifest declares every pSEO URL the site should publish. Each entry holds the slug, the page metadata, an image prompt, and the internal-link block.
- At build time, the Next.js app reads the manifest, runs
generateStaticParamsto enumerate every/p/<slug>route, and emits one static HTML file per leaf plus a composedsitemap.xml. - Per-slug images are generated out of band by a separate script. The script HEAD-checks each image on the CDN; if it already exists, the slug is skipped. New slugs trigger a generate-and-upload pass.
- The CDN (
images.alkenacode.devin this case study, distinct from the build host) serves the images with aggressive cache headers. Filenames are deterministic, so cache hits are the rule. - The sitemap is submitted to Google Search Console once; subsequent additions trigger an IndexNow ping on deploy.
The boundary that matters most is the third one. Image generation is out of band, not coupled to the build. This means:
- Adding a new slug to the manifest does not require regenerating any existing image.
- Rebuilding the site is fast; image generation is slow.
- A failure in the image generator does not break the build.
What lives where
| Layer | Repo | Lifecycle |
|---|---|---|
| Slug manifest | content/slugs.ts in this app | Edited per release |
| Page renderer | Next.js app code | Edited rarely; one template covers all leaves |
| Image generator | scripts/gen-images.ts | Run when slugs are added or prompts change |
| CDN | external nginx + filesystem | Long-lived; written to via rsync or scp |
| Sitemap | Next.js sitemap.ts | Composed at build time from the manifest |
The next piece in the spine, Slug strategy, describes how the slug manifest itself is generated and curated.