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.