Skip to content

Prompts

Copy-paste AI prompts

Drop these into Cursor, Claude, or a similar assistant. Every prompt starts from the official docs llms.txt; never invent APIs.

These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Add Live Preview to a Next.js frontend

    Implement the documented Live Preview contract (URL template tokens, signed token, GET /api/v1/preview) in a Next.js app.

    • Live Preview
    • Next.js
    • Content versioning
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/live-preview.md
       - https://docs.externa.qiick.io/docs/content-versioning.md
       - https://docs.externa.qiick.io/docs/headless-starter.md
       - https://docs.externa.qiick.io/docs/public-cms-api.md
       - https://docs.externa.qiick.io/docs/public-cms-api-types.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY endpoints, parameters, field types, permission names, env vars and UI paths that appear in those docs (or in the starter's code, if I paste it). If something is not documented, say "not documented — check the docs" instead of inventing it.
    - Cite the docs page (URL) for each important step.
    - Clearly separate Externa behavior from framework/host behavior (Next.js, Nuxt, Vercel, Docker, etc.).
    - Never ask me to paste secrets (API keys ek_…, APP_KEY, webhook secrets) into this chat; use placeholders.
    - Before finishing, list any assumptions you made and anything I should double-check against my installed version.
    
    GOAL: Help me add Externa Live Preview to my Next.js App Router site (based on qiick-io/externa-next-starter).
    
    STEPS TO HELP WITH:
    1. Tell me how to enable content versioning on the collection, so drafts exist.
    2. Propose a Live Preview URL template using only the documented tokens ({{id}}, {{collection}} / {{slug}} — both are the COLLECTION slug, {{locale}}, {{version}}, {{token}}) and tell me where to set it (collection drawer or Settings → Project default).
    3. Implement a preview route that reads `token` from the query and calls GET {EXTERNA_API_URL}/api/v1/preview?token=… with no caching (reuse the starter's `externaFetch()`); render `data` with the same components as my production pages and show `meta.version` / `meta.expires_at` in a banner.
    4. Handle the documented errors (422 missing token, 403 invalid/expired) with a friendly "click Live Preview again" message.
    5. Account for the payload shape: a draft returns the raw `draft_data` bag (translatable fields as locale maps, files and relations as ids); a published preview is a flattened item without `include` expansion (files are ids too).
    6. Explain draft vs published per the content-versioning docs, and confirm the Public CMS API keeps returning published values.
    7. Never put API keys in preview URLs; if Allowed origins is set, send the API key as a server-side header. Mark preview pages noindex.
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - Frontend / stack: <e.g. Next.js 15 App Router on Vercel>
    - What I already have: <paste relevant schema, files, or errors — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Draft → review → publish workflow

    Enable content versioning and editorial approvals: submit, in_review, approve/reject, then Publish.

    • Content versioning
    • Approvals
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/content-versioning.md
       - https://docs.externa.qiick.io/docs/approvals.md
       - https://docs.externa.qiick.io/docs/roles-and-permissions.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY states, UI labels, and permissions from those docs. Do not invent a multi-branch versions engine — Externa uses lean draft_data + publish.
    - Cite the docs page (URL) for each important step.
    - Never ask me to paste secrets into this chat.
    - Before finishing, list assumptions and what I should verify on my collections.
    
    GOAL: Help me set up a draft → review → publish editorial workflow on Externa collections.
    
    STEPS TO HELP WITH:
    1. On the collection edit drawer: turn on Versioning first, then Approvals required. Approvals without versioning are rejected.
    2. Explain Draft vs Published workspaces: Draft edits `draft_data` only; Published is read-only while versioning is on. Publish (promote) copies draft_data into published values and clears the draft; Discard drops draft_data. Both need `can-edit-collections` (+ item write access).
    3. Map the approval states exactly: draft → submit → in_review → approve → approved → Publish → published (approval resets). Reject (+ note) → rejected → edit/resubmit → in_review. Saving a draft while in_review/approved/rejected invalidates approval back to draft.
    4. Permissions: `can-submit-collections` to submit; `can-approve-collections` to approve/reject (note required on reject); `can-edit-collections` to publish/discard/edit. Point reviewers at the In review filter on the items list.
    5. Note scheduled publish also requires `approved` when approvals are on, and needs `collections:process-schedules` / a running scheduler.
    6. Optional outbound webhook events: `item.submitted`, `item.approved`, `item.rejected` (plus `item.published` on promote). Remind me this is not a BPM / e-sign product.
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - Collections: <slugs that need review>
    - Roles already created: <editor / reviewer / …>
    - What I already have: <paste notes — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Migrate from Directus into Externa

    Import Directus items via profile=directus, with the first-locale-only translations caveat and dry-run upsert.

    • Migration
    • AI tools
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/cms-import.md
       - https://docs.externa.qiick.io/docs/ai-imports-and-sync.md
       - https://docs.externa.qiick.io/docs/field-types.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY endpoints, parameters, field types, permission names, env vars and UI paths that appear in those docs. If something is not documented, say "not documented — check the docs" instead of inventing it.
    - Cite the docs page (URL) for each important step.
    - Never ask me to paste secrets into this chat; use placeholders.
    - Before finishing, list assumptions and what I should verify on my installed version.
    
    GOAL: Help me migrate content from Directus into Externa using ImportRemoteJson with profile=directus.
    
    STEPS TO HELP WITH:
    1. Confirm the path is CMS import connectors on top of AI remote JSON import (AI chat preset: "Import from Directus URL").
    2. Tell me to allowlist the Directus host in `AI_REMOTE_IMPORT_HOSTS`.
    3. Dry-run first: ImportRemoteJson with a Directus items URL (e.g. https://cms.example/items/pages), `profile=directus`, `dry_run=true`, `upsert_key=slug` (or another stable key), and `auth_bearer=…` when needed.
    4. Explain what profile=directus does: drop Directus system fields (`user_created`, `date_*`, …) and promote first translation scalars (`title`, `body`, …) onto the row.
    5. Emphasize the locale caveat: Directus `translations[]` → first locale scalars only; a full locale matrix is out of scope for v1. Advise modeling Externa translatable fields afterward if I need more locales (field-types docs).
    6. After preview looks right, re-run with `dry_run=false`. Note ~200 async threshold / max 500 rows per call, media not auto-downloaded, relations as JSON strings unless reshaped upstream, one-way import only.
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - Directus items URL (no secrets): <e.g. https://cms.example/items/pages>
    - Target collection: <existing slug or create new>
    - What I already have: <paste schema/errors — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Migrate WordPress posts into Externa

    Import WordPress REST posts via ImportRemoteJson profile=wordpress, Application Passwords, dry-run, and upsert.

    • Migration
    • AI tools
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/cms-import.md
       - https://docs.externa.qiick.io/docs/ai-imports-and-sync.md
       - https://docs.externa.qiick.io/docs/ai-configuration.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY endpoints, parameters, field types, permission names, env vars and UI paths that appear in those docs. If something is not documented, say "not documented — check the docs" instead of inventing it.
    - Cite the docs page (URL) for each important step.
    - Never ask me to paste secrets (API keys ek_…, APP_KEY, webhook secrets, Application Passwords) into this chat; use placeholders.
    - Before finishing, list assumptions and what I should verify on my installed version.
    
    GOAL: Help me migrate WordPress posts into Externa collections using the CMS import connectors (ImportRemoteJson with profile=wordpress).
    
    STEPS TO HELP WITH:
    1. Confirm the migration path is the existing AI remote JSON import — not a second sync engine — and that AI chat presets include "Import from WordPress REST".
    2. Tell me to allowlist the WordPress host in `AI_REMOTE_IMPORT_HOSTS` before fetching.
    3. Walk me through a dry-run first: ImportRemoteJson with url pointing at `/wp-json/wp/v2/posts` (or a custom post type route), `profile=wordpress`, `dry_run=true`, and a sensible `upsert_key` (e.g. slug). Explain that profile=wordpress unwraps `{ rendered: "…" }` envelopes on first-level keys (`title`, `content`, `excerpt`).
    4. For Application Passwords: use `auth_header` as `Basic …` when Bearer is not used (docs also allow `auth_bearer`). Never ask me to paste the real password.
    5. After I confirm the proposed fields / preview rows (zero writes), re-run with `dry_run=false`. Note row caps (~200 queue threshold, max 500 per call) and that large payloads queue via ImportCollectionJob.
    6. Call out documented v1 gaps: featured images / file UUIDs are not auto-downloaded into Externa File rows; relations stay JSON strings unless reshaped upstream; import is one-way (no write-back).
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - WordPress REST URL (no secrets): <e.g. https://blog.example.com/wp-json/wp/v2/posts>
    - Target collection: <existing slug or create new>
    - What I already have: <paste schema/errors — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Model collections with Cursor or Claude

    Design collections and fields using Context7 IDs, llms.txt, collection packs, field packs, and field conditions.

    • Collections
    • AI tools
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
       - https://docs.externa.qiick.io/docs/collections.md
       - https://docs.externa.qiick.io/docs/field-types.md
       - https://docs.externa.qiick.io/docs/field-conditions.md
       - https://docs.externa.qiick.io/docs/extending.md
    3. Prefer Context7 when available:
       - /qiick-io/externa-core — package source / admin internals
       - /llmstxt/externa_qiick_io_llms_txt — published docs from llms.txt
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY field types, pack names, UI labels, and settings keys that appear in the docs. Never invent FieldTypeEnum values or pack slugs.
    - Cite the docs page (URL) for each important step.
    - Never ask me to paste secrets into this chat.
    - Before finishing, list assumptions and what I should verify in the admin UI.
    
    GOAL: Help me model Externa collections (and fields) for my content with Cursor/Claude, starting from packs when they fit.
    
    STEPS TO HELP WITH:
    1. Ask what content I need (blog, pages, products, custom). Prefer official collection packs when they match: `seo`, `categories`, `pages`, `articles`, `products` (Collections → Create from pack…). Missing dependencies are auto-created; existing slugs are reused.
    2. For SEO on Articles/Pages/Products, prefer the SEO collection pack + M2O relation — not `seo_inline` unless I need denormalized `seo_*` fields on an existing collection. Field packs apply via Fields → Add field pack… (existing names skipped).
    3. When packs are not enough, design fields using only documented FieldTypeEnum values and settings from field-types. Call out that `is_singleton` cannot be changed after create.
    4. Add field conditions only with the documented shape (`logic` and/or `or`, `rules` with operators like equals / not_equals / contains / empty / not_empty / gt / gte / lt / lte / in / not_in, plus `hidden` / `readonly` / `required`).
    5. If I need a custom field type or permission later, point me at Extending Externa (enum + sync + tests) — do not invent a half-implemented type.
    6. Give me a concise schema checklist I can click through in the admin, with docs citations.
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - Content I need: <e.g. docs site with guides + authors>
    - What I already have: <paste existing collection JSON or screenshots — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Multilingual landing with the Nuxt starter

    Locale-aware landing page (en/it) with qiick-io/externa-nuxt-starter, translatable fields, and the Translation workspace.

    • Starter
    • Nuxt
    • i18n
    • Translations
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/headless-starter.md
       - https://docs.externa.qiick.io/docs/translation-workspace.md
       - https://docs.externa.qiick.io/docs/collections-data-model.md
       - https://docs.externa.qiick.io/docs/project-settings.md
       - https://docs.externa.qiick.io/docs/collections.md
       - https://docs.externa.qiick.io/docs/field-types.md
       - https://docs.externa.qiick.io/docs/public-cms-api.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY endpoints, parameters, field types, permission names, env vars and UI paths that appear in those docs (or in the starter's code, if I paste it). If something is not documented, say "not documented — check the docs" instead of inventing it.
    - Cite the docs page (URL) for each important step.
    - Clearly separate Externa behavior from framework/host behavior (Next.js, Nuxt, Vercel, Docker, etc.).
    - Never ask me to paste secrets (API keys ek_…, APP_KEY, webhook secrets) into this chat; use placeholders.
    - Before finishing, list any assumptions you made and anything I should double-check against my installed version.
    
    GOAL: Help me build a multilingual landing page (e.g. en + it) with the official Nuxt starter (qiick-io/externa-nuxt-starter, Nuxt 3) on top of Externa.
    
    STEPS TO HELP WITH:
    1. From the docs, explain how to enable content languages in Settings → Project → Content languages and how translatable fields are stored (one value row per locale).
    2. Help me model a singleton `landing` collection (is_singleton cannot be changed after create) and choose which fields are translatable according to the field-types docs.
    3. Explain how editors use the Translation workspace on the item form (locale dropdown with filled/total completeness; **Apply to all locales** / **Apply to empty locales**; per-field **Copy from {{locale}}** and optional **Translate with AI from {{locale}}** when the user has `can-use-ai` and local AI is configured).
    4. Write a Nitro server route that reuses the starter's `externaFetch(event, path)` from server/utils/externa/client.ts (private runtimeConfig, never runtimeConfig.public / NUXT_PUBLIC_) and calls /api/v1 with the documented `locale` param (enabled locales only, else 422). Read the locale from a route param with getRouterParam, like the starter's server/api/items/[id].get.ts.
    5. Explain what the API returns for a missing translation: with `locale`, Externa falls back along the project's fallback chain (default locale first, then the other enabled locales); with `include_all_translations=true` a missing locale is simply absent. The starter adds no fallback logic of its own.
    6. Write a pages/[locale] page with a language switcher and absolute hreflang links.
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - Frontend / stack: <e.g. Nuxt 3 on Netlify>
    - What I already have: <paste relevant schema, files, or errors — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Rebuild Vercel on Externa content change

    Wire outbound HMAC webhooks to a thin receiver that triggers a Vercel Deploy Hook on item.published.

    • Webhooks
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/webhooks.md
       - https://docs.externa.qiick.io/docs/webhook-rebuild-purge.md
       - https://docs.externa.qiick.io/docs/automation-without-flows.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY documented event types, headers, and Project settings fields. Externa has no Flows canvas — prefer outbound webhooks + a thin receiver.
    - Cite the docs page (URL) for each important step.
    - Never ask me to paste webhook secrets or Deploy Hook URLs with secrets into this chat; use placeholders.
    - Before finishing, list assumptions and a verification plan (Send test event / ping).
    
    GOAL: When editors publish content in Externa, rebuild my Vercel frontend safely.
    
    STEPS TO HELP WITH:
    1. Configure Admin → Settings → Project: Webhook URL + signing secret (both required). Delivery is queued (`DeliverOutboundWebhookJob`) — a queue worker must run. Optional Send test event (`type: ping`).
    2. Prefer Pattern A from webhook-rebuild-purge: Externa → my HTTPS receiver → verify `X-Externa-Signature` (HMAC-SHA256 over raw body, `sha256=` prefix) → on matching `type`, POST the Vercel Deploy Hook. Do NOT expose an unsigned Deploy Hook as the public Externa webhook URL in production (hooks ignore HMAC; anyone with the URL can rebuild).
    3. Event picks: listen for `item.published` when only live content should rebuild; use `item.created` / `item.updated` only if draft saves should rebuild too. Filter on JSON `type`.
    4. Show a minimal Node receiver sketch matching the docs (timing-safe compare, then `fetch(deployHook, { method: 'POST' })`). Create the Deploy Hook in Vercel → Project → Settings → Git → Deploy Hooks.
    5. Remind me: outbound webhooks are Externa → my URL (not an inbound Externa route). Do not confuse with `POST /ai/webhooks/collection-import`. Bodies are minimal (ids/slug). Retries: 3 tries with backoff.
    6. Optional: Cloudflare purge after publish is a separate Pattern B — only if I ask.
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - Frontend host: <Vercel project name>
    - Receiver host: <e.g. small Node/Edge function URL>
    - What I already have: <paste envelope samples/errors — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Roles and permissions for an editorial team

    Set up Spatie roles, groups, Collection access, and approval permissions for editors and reviewers.

    • Permissions
    • Approvals
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/roles-and-permissions.md
       - https://docs.externa.qiick.io/docs/permissions.md
       - https://docs.externa.qiick.io/docs/users-and-groups.md
       - https://docs.externa.qiick.io/docs/approvals.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY permission names from PermissionEnum / the roles-and-permissions catalog. Never invent ad-hoc permission strings.
    - Cite the docs page (URL) for each important step.
    - Never ask me to paste secrets into this chat.
    - Before finishing, list assumptions and what I should verify after permissions:sync.
    
    GOAL: Help me design roles and permissions for an editorial team (editors, reviewers, maybe readers) in Externa admin.
    
    STEPS TO HELP WITH:
    1. Explain seeded roles: `super-admin`, `admin`, `reader`, and system role `public` (anonymous Public CMS API). Note that `public` is not assignable to users — only Collection access + Files access are editable on it.
    2. Clarify the two layers: Spatie / PermissionEnum gates the admin UI; Collection access / Files access matrices gate the Public CMS API independently.
    3. Propose custom roles (e.g. editor, reviewer) using only documented permissions. For approvals workflow, include `can-submit-collections` (submit draft for review) and `can-approve-collections` (approve/reject). Editors who publish need `can-edit-collections`. Sync with `php artisan permissions:sync` (and UI Sync from enum) — do not invent names outside the enum.
    4. For large teams: attach roles to a group so members inherit Spatie permissions and the role’s collection/file matrices (no separate group→collection ACL).
    5. Remind me `super-admin` cannot be deleted/renamed/duplicated; `public` cannot be renamed/deleted/duplicated; Prefer groups over per-user role spam.
    6. Optional: sketch Collection access for the `public` role (Read only on public collections; Files Read without Read private) vs an API-key role for backends.
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - Team shape: <e.g. 3 editors, 2 reviewers, public website>
    - Collections involved: <slugs>
    - What I already have: <paste role screenshots/notes — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Self-host Externa with Docker in production

    Deploy via GHCR Compose quick/prod path, PHP 8.4.27 / 8.5.12 minimum, healthchecks, and reverse proxy TLS.

    • Docker
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/deploy-with-docker.md
       - https://docs.externa.qiick.io/docs/deployment.md
       - https://docs.externa.qiick.io/docs/reverse-proxy.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY Compose files, env vars, health endpoints, and proxy settings from those docs. Never invent image tags or entrypoint flags.
    - Cite the docs page (URL) for each important step.
    - Never ask me to paste APP_KEY, DB_PASSWORD, or other secrets into this chat; use placeholders.
    - Before finishing, list assumptions and a post-deploy smoke checklist.
    
    GOAL: Help me self-host Externa in production with Docker (official GHCR image) behind TLS.
    
    STEPS TO HELP WITH:
    1. PHP runtime floor: composer declares `^8.4.27` (**PHP 8.4.27+ or 8.5.12+**). Official `ghcr.io/qiick-io/externa-core:1.2.2` / `latest` is built on `php:8.4.27-fpm-bookworm` with a hardened `php.ini` (`session.upload_progress.enabled=0`, `session.use_strict_mode=1`, body/multipart limits matching nginx 100M). Pull and recreate (`docker compose pull && docker compose up -d`), then `docker compose exec <php-service> php -v`. Source builds: rebuild with `--pull --no-cache`.
    2. Quick deploy path from an externa-core checkout: copy `.env.docker.quick.example` → `.env`, set APP_KEY / strong DB_PASSWORD / APP_URL, then `docker compose -f compose.quick.yaml up -d`. Pin with `EXTERNA_IMAGE=ghcr.io/qiick-io/externa-core:1.2.2` when needed.
    3. Explain gated first boot: `RUN_MIGRATIONS` / `RUN_SEED` (samples enable migrate; seed is opt-in with INITIAL_SUPER_ADMIN_*). After login works, set `RUN_SEED=false`.
    4. Health: `GET /health/ready` (Compose app probe), also `/health/live` and Laravel `/up`.
    5. For public HTTPS + Reverb: follow reverse-proxy cookbook (Caddy / Traefik / nginx). Set `APP_URL` to the browser HTTPS URL, `TRUSTED_PROXIES`, and browser-facing `REVERB_*` / `VITE_REVERB_*` (rebuild image after Vite Reverb public URL changes).
    6. Build-from-source prod alternative: `.env.docker.prod.example` + `compose.prod.yaml` (+ managed overlay when DB/Redis are external). Do not invent Sail as the production path.
    
    MY CONTEXT (fill in):
    - Host / cloud: <e.g. Hetzner VPS>
    - Domain: <e.g. https://cms.example.com>
    - Prefer quick GHCR vs build-from-source: <choose>
    - What I already have: <paste compose/.env keys only (names) — no secret values>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.

  • Wire the Next.js starter into a blog

    Turn qiick-io/externa-next-starter into a blog (list + slug pages) on the Articles collection pack, using the Public CMS API.

    • Starter
    • Next.js
    • Public CMS API
    You are helping me with Externa, an open-source headless CMS for Laravel (documented core version 1.2.2).
    
    BEFORE WRITING ANY CODE OR ADVICE:
    1. Read https://docs.externa.qiick.io/llms.txt first. It lists every docs page as Markdown.
    2. Then read these pages (fetch the .md versions):
       - https://docs.externa.qiick.io/docs/headless-starter.md
       - https://docs.externa.qiick.io/docs/public-cms-api.md
       - https://docs.externa.qiick.io/docs/public-cms-api-types.md
       - https://docs.externa.qiick.io/docs/field-types.md
       - https://docs.externa.qiick.io/docs/roles-and-permissions.md
       - https://docs.externa.qiick.io/docs/quick-start.md
       - https://docs.externa.qiick.io/docs/ai-coding-tools.md
    3. Optional: pull docs via Context7 MCP using library IDs /qiick-io/externa-core and/or /llmstxt/externa_qiick_io_llms_txt.
    4. If you cannot fetch URLs, tell me and ask me to paste those pages. Do not guess.
    
    RULES:
    - Use ONLY endpoints, parameters, field types, permission names, env vars and UI paths that appear in those docs (or in the starter's code, if I paste it). If something is not documented, say "not documented — check the docs" instead of inventing it.
    - Cite the docs page (URL) for each important step.
    - Clearly separate Externa behavior from framework/host behavior (Next.js, Nuxt, Vercel, Docker, etc.).
    - Never ask me to paste secrets (API keys ek_…, APP_KEY, webhook secrets) into this chat; use placeholders.
    - Before finishing, list any assumptions you made and anything I should double-check against my installed version.
    
    GOAL: Help me turn the official Next.js starter (qiick-io/externa-next-starter, Next.js 15 App Router) into a blog with a /blog index and /blog/[slug] pages, reading an `articles` collection from Externa's Public CMS API (/api/v1).
    
    STEPS TO HELP WITH:
    1. Confirm from the docs how to create the `articles` collection with the Articles collection pack (Collections → Create from pack…) and which fields and relations it creates. Note that `body` is a `blocks` field (block types `section` and `rich_text`), so its value is an array of { id, type, data } and nested translatable fields keep their locale map.
    2. Tell me exactly which grants the `public` role (or an API-key role) needs: Collection access → Read on `articles` and `categories`, Files access → Read for covers.
    3. Write a server-only blog helper that reuses the starter's `externaFetch()` from lib/externa/client.ts and ONLY documented query params (page, per_page, filter[field][_eq], include, locale, include_all_translations). Use `include=files,category` to expand the cover and category.
    4. The items endpoint has no sort parameter (items come back newest-first by id), so sort by `published_at` in my code and explain the per-page limitation.
    5. Generate the index and slug pages plus a renderer for the blocks body. Keep EXTERNA_API_KEY server-side (never NEXT_PUBLIC_).
    6. Remind me that, once Allowed origins is set, server-side requests need an API key, and that browser image requests to /api/v1/files are behind the same origin gate.
    
    MY CONTEXT (fill in):
    - Externa URL (local/staging): <e.g. http://externa-core.test>
    - Frontend / stack: <e.g. Next.js 15 App Router on Vercel>
    - What I already have: <paste relevant schema, files, or errors — no secrets>

    These prompts tell your assistant to read the official docs first (llms.txt and Context7 IDs /qiick-io/externa-core and /llmstxt/externa_qiick_io_llms_txt). Always verify generated code, and never paste API keys, APP_KEY, or webhook secrets into a chat.