name: statamic-cms
description: Use when working with Statamic 6 features in this project — creating or modifying collections, entries, blueprints, fieldsets, taxonomies, globals, navigations, assets, forms; running the please CLI; configuring the Control Panel or SEO Pro; or anything under content/, resources/blueprints/, or config/statamic/. Statamic-specific concepts that are not covered by the generic Laravel skills.
metadata:
version: "1.1.0"
domain: cms
triggers: Statamic, collection, entry, blueprint, fieldset, taxonomy, global, navigation, please, control panel, cp, antlers, statamic tag, seo pro, form, page builder
Statamic CMS (this project)
Statamic 6.x (currently 6.21) with Pro enabled. This is a Laravel package, so all Laravel conventions still apply — but content management has its own model. Read [[statamic-eloquent-driver]] first when touching content: this project stores content (and users) in MySQL, not flat files. When writing or editing any copy, follow [[content-voice]]: wording must read human-written (no em-dashes, no AI constructions).
This is the site build for Aligned Life — Melissa Alexander's hypnotherapy practice (RTT). Primary CTA everywhere: "Book a Free 15-Minute Discovery Call" (URL from the site_settings global).
What's enabled in .env
| Var | Value | Meaning |
|---|---|---|
APP_NAME |
"Aligned Life" | Used as SEO site name + site display name |
APP_URL |
https://alignedlife.test | https — Herd serves TLS; SEO Pro builds absolute URLs from this |
STATAMIC_PRO_ENABLED |
true | Required for revisions; trial mode locally |
STATAMIC_TWO_FACTOR_ENABLED |
true | 2FA available on CP accounts |
STATAMIC_TWO_FACTOR_ENFORCED |
false | When true, enforces 2FA for super_users (see config/statamic/users.php). Keep false locally; set true in production |
STATAMIC_REVISIONS_ENABLED |
true | Revisions/working copies on (enabled per collection too) |
STATAMIC_GRAPHQL_ENABLED |
false | No GraphQL endpoint |
STATAMIC_API_ENABLED |
false | No content API |
STATAMIC_GIT_ENABLED |
false | Content backup is composer content:export, not Statamic Git |
STATAMIC_STATIC_CACHING_STRATEGY |
null | Static caching off (later-phase task) |
If a feature isn't working, check the env var before debugging code.
Content model
| Collection | Route | Mount | Notes |
|---|---|---|---|
pages |
{parent_uri}/{slug} |
— | Structured, root = Home (id: home). Blueprint pages (title + page_builder + SEO + template picker) |
services |
{mount}/{slug} → /services/… |
Services page ffa70020-b103-4ca2-967c-479d5770e30c |
Orderable (max_depth 1). Blueprint service: title, intro, icon (select: brain, child, compass, hands, headphones, heart, lotus, scales, shield, sparkles), image, page_builder, faqs grid, SEO. 9 seeded services: 6 treatment areas + Reiki Healing, Personalised Hypnosis Recordings, Trauma-Informed Coaching (added 2026-06-12; the home services_grid is pinned to the 6 treatment areas) |
articles |
{mount}/{slug} → /resources/… |
Resources page 002274bf-2feb-47cb-92b1-3552fc3b1bb1 |
Dated (past public / future private), sort desc. Blueprint article: title, excerpt, cover_image, page_builder, SEO |
testimonials |
none (not routable) | — | Blueprint testimonial: title (client name), quote, context, service (entries, max 1). inject.seo: false keeps them out of SEO Pro reports/sitemap |
Pages seeded: Home /, About Melissa /about, Hypnosis & RTT /hypnosis-rtt, Services /services, Resources /resources, Contact /contact.
Navs: main (About, Hypnosis & RTT, Services, Resources, Contact) and footer — trees reference page entries.
Global set: site_settings — contact_email, contact_phone, booking_url (currently /contact placeholder), facebook/instagram/youtube/tiktok URLs, footer_tagline. Blueprint at resources/blueprints/globals/site_settings.yaml. (A footer disclaimer field existed until 2026-06-12; removed at Ryan's request — template block, blueprint field, and value all deleted. Don't reintroduce it as a "fix".) Handles as of 2026-06-12: instagram_url is @thealignedlife.w.melissa; youtube_url stays the @alignbmcenergy business channel (free-audio embeds link @FreeRTTHypnosisAudios-b6h directly instead — deliberate split, per Ryan).
Form: contact (name, email, phone, enquiry) with honeypot field website. The message field handle is deliberately enquiry, not message — message is a reserved word in Statamic's form email context. All fields carry max-length rules (name 120, email 254, phone 30, enquiry 5000) — keep bounds on any new field. No email config yet (mail is log locally); submissions are stored in DB and visible in CP → Forms. Covered by tests/Feature/ContactFormTest.php (happy/validation/max/honeypot), which loads the real committed blueprint.
Asset container: assets → public/assets disk. Contains 8 images registered as eloquent assets with alt text: og-default.jpg (load-bearing for social sharing — do not delete or rename without updating resources/addons/seo-pro.yaml), two real photos of Melissa for the home and About page image+text sections (portrait-melissa.jpg, portrait-melissa-about.jpg — replaced the placeholders 2026-06-12; outdoor autumn shoot, 1463×2048), plus placeholder images covering: home hero (hero-home.jpg), CTA background (cta-forest-path.jpg), Hypnosis & RTT page (rtt-calm-space.jpg), and two article covers (cover-overthinking.jpg, cover-hypnosis-audios.jpg). No service images (explicitly declined). Glide image presets configured in config/statamic/assets.php: sm (640px), md (1024px), lg (1600px), xl (2400px) — all webp q80. Use {{ partial:img }} for all asset rendering (see [[antlers-templating]]).
Blueprints & fieldsets
- Reusable fieldsets in
resources/fieldsets/:seo(seo_title, seo_description, og_image — imported into every entry blueprint),page_builder(the replicator with all sets),faq_items(thefaqsgrid, shared between the service blueprint and thefaqreplicator set via field referencefaq_items.faqs). - Page-builder replicator sets:
hero,text,image,cta,comparison,services_grid,testimonials_slider,youtube_embed(optionalmore_url/more_labelbrowse link under the embed),faq,steps,trust_strip,image_text,programs(package cards: title, duration badge, description, includes list). CTA/hero button label + URL fall back to the discovery-call default andsite_settings.booking_urlin the partials. The herosubheadingsupports inline markdown for a serif name accent (the homepage emphasises Melissa Alexander this way; see [[antlers-templating]]).ctahas an optionalimagefield (full-bleed photo variant when set).image_textfields: image, image_side (left/right), eyebrow, heading, text (markdown), checklist, optional button (renders only when both label and url present). - Canonical blueprint YAML in v6 is
tabs:→ (named tab) →sections:→fields:. Hand-written legacysections:maps are accepted and auto-migrated on import, but exports rewrite totabs:— author new blueprints in tabs format to keep diffs clean.
SEO Pro
statamic/seo-pro (^7.10) is installed. {{ seo_pro:meta }} renders all meta in the layout head. Site defaults live in addon settings (DB) — snapshot at resources/addons/seo-pro.yaml:
- title
{{ seo_title ?? title }}, description{{ seo_description ?? excerpt ?? intro }}— i.e. the customseofieldset feeds defaults, entry titles are the fallback. Don't put "| Aligned Life" in seo_title values; the site name is appended automatically (|separator, configured assite_name_separatorinresources/addons/seo-pro.yaml). - Default social image:
image: og-default.jpgwired in the site defaults.config/statamic/seo-pro.phpis published withassets.container = 'assets'so Glide can process the image.og-default.jpgmust exist inpublic/assetsand be registered as an asset — do not rename without updating both places. - Per-collection inject cascade:
pagesandservicescollections useinject: { seo: { image: '@seo:og_image' } }(falls back to the site default og image);articlesuseinject: { seo: { image: '@seo:cover_image' } }(resolves from the entry'scover_imagefield). This@seo:fieldsource syntax preserves the Asset object — do not replace it with an Antlers expression (SEO Pro's Cascade casts those to string and the meta template then receives a string, not an Asset, breaking the<meta property="og:image">tag). - Sitemap at
/sitemap.xml(testimonials excluded viainject.seo: false), humans.txt enabled, JSON-LD organization + breadcrumbs. - Per-entry overrides exist in the injected "SEO" tab on publish forms (stored in the entry's
seoarray) — prefer the custom fields, use the injected tab only for canonical/robots edge cases.
The please CLI
Statamic's own CLI lives at the project root: php please <command> (not php artisan). Discover commands with php please list. Most relevant groups:
eloquent:*— import/export between DB and flat files. Prefercomposer content:exportfor snapshots. See [[statamic-eloquent-driver]] for the gotchas (no--forceon import-entries, stale URI columns, stache clearing).make:*— scaffold tags, fieldtypes, modifiers, addons, widgets, scopes, actions (e.g.app/Modifiers/YoutubeEmbedUrl.phpcame frommake:modifier).stache:*—stache:clearafter any direct DB or flat-file change.auth:migration— generated the statamic user columns + role_user/group_user + webauthn migrations (already run; users table uses uuid ids).
php artisan is still used for Laravel things (migrations, routes, tinker, tests, pail).
Control Panel
- URL:
/cp(underhttps://alignedlife.test/cp), login ryan@mortier.ca (super). - Revisions are on: publishing flows through working copies on pages/services/articles/testimonials.
- Built with Inertia.js + Vue 3 — extending the CP means
php please setup-cp-vite. - Dashboard widgets live in
config/statamic/cp.php(widgets): a welcome panel (template→resources/views/widgets/welcome.blade.php), the built-informwidget oncontact("New Enquiries"),collectionwidgets forarticlesandtestimonials, SEO Pro'sseo_proreport, andupdater. Statamic 6 shipscollection/template/updater/form; SEO Pro addsseo_proandrecent_errors. An unregistered handle 500s the dashboard, so checkapp('statamic.widgets')->keys()before adding one. Blade (html()) widgets inject raw markup into the Inertia dashboard: wrap content in<ui-widget title="…">for card chrome and avoid app Tailwind utilities (purged from the CP build), using inline styles +currentColorfor theme safety. Covered bytests/Feature/DashboardWidgetsTest.php.
When this skill is wrong
Update this file whenever:
- A new env var is flipped in
.env - A collection, taxonomy, blueprint, fieldset, global, nav, or form is created/renamed
- SEO Pro defaults change meaningfully
- A custom tag/fieldtype/modifier/addon is added under
app/
References
- Statamic docs: https://statamic.dev/ (append
.mdto most doc URLs for raw markdown, e.g.https://statamic.dev/content-modeling/collections.md) - LLM-targeted docs index: https://statamic.dev/llms.txt
- SEO Pro docs: vendor/statamic/seo-pro/DOCUMENTATION.md
- Boost
search-docstool is weak for Statamic specifics — prefer the.mddoc URLs or vendor source