SDK CLI
@cachely-io/sdk ships a deterministic CLI for bootstrapping Cachely in your project. It detects your framework and CMS provider, generates a typed helper file, and updates .env.example — without touching any existing source files.
Commands
npx @cachely-io/sdk <command>
Commands:
setup Generic helper-file generation for any framework + CMS.
setup --provider prismic Provider-specific onboarding (Nuxt + Prismic) — same as below.
setup prismic Provider-specific onboarding (Nuxt + Prismic).
init prismic Alias for `setup prismic`.
setup --provider contentful Provider-specific onboarding (Contentful).
setup contentful Same as above.
init Print available providers for provider-specific onboarding.
Since 0.12.0:
setup --provider prismicandsetup prismicare equivalent. Earlier versions dropped the flag form to the generic helper-only flow — that bug is fixed.
Generic setup
Use this path for any framework and CMS combination:
npx @cachely-io/sdk setup
The CLI:
- Detects your framework — Next.js, Nuxt, Vite, or generic
- Detects your CMS provider — Prismic, Contentful, Sanity, Storyblok, Shopify, or generic
- Detects your package manager — pnpm, npm, yarn, or bun
- Generates a typed helper file
- Adds
CACHELY_PROXY_URLto.env.example - Installs
@cachely-io/sdk
Generated helper locations
| Framework | File |
|---|---|
| Next.js | lib/cachely.ts |
| Nuxt | composables/useCachely.ts (or utils/cachely.ts if your project uses utils/) |
| Vite / generic | cachely.ts |
Flags
| Flag | Description |
|---|---|
--yes | Non-interactive. Accept all detected defaults. |
--dry-run | Print every planned action; write nothing; skip install. |
--tenant <slug> | Hard-code your Cachely tenant slug into the generated helper. |
--proxy-url <url> | Full proxy URL (e.g. https://my-project.cachely.io). Derives --tenant if not given; seeds .env.example. |
--provider <id> | prismic · contentful · sanity · storyblok · shopify · generic. Since 0.12.0, prismic / contentful / sanity / storyblok route to that provider's onboarder (equivalent to setup <provider>); shopify / generic use the generic helper flow. |
--framework <id> | next · nuxt · vite · generic |
--dir <path> | Project root (default: cwd). |
-h, --help | Show help. |
Provider-specific flags (Prismic onboarder):
| Flag | Description |
|---|---|
--composables / --patch-client / --no-patch-client | Integration mode. Combine the first two for 'both'. |
--transforms / --no-transforms | Write docs/cachely/transforms.md documenting cachely: { transform }. |
--experiments / --no-experiments | Wire useCachelyExperiments() into the generated composable. |
--custom-domain / --no-custom-domain | Generate customDomain: true in the client. |
Examples
# Auto-detect everything (interactive)
npx @cachely-io/sdk setup
# Prismic + Nuxt (rich onboarder, both forms equivalent since 0.12.0)
npx @cachely-io/sdk setup --provider prismic --tenant my-project --yes
npx @cachely-io/sdk setup prismic --tenant my-project --yes
# Preview without writing
npx @cachely-io/sdk setup --dry-run --provider prismic --tenant my-project
# Prismic with AI Transforms doc + experiments wiring
npx @cachely-io/sdk setup --provider prismic --tenant my-project --transforms --experiments --yes
# Force composables-only (do not touch existing Prismic client)
npx @cachely-io/sdk setup --provider prismic --tenant my-project --composables --yes
# Non-interactive CI mode (Next + Contentful — routes to the Contentful onboarder since 0.12.0)
npx @cachely-io/sdk setup --yes --tenant my-project --provider contentful --framework next
Provider-specific onboarding
For a more guided, CMS-specific setup, use the provider commands.
Prismic onboarding
All three of these commands are equivalent — they reach the same rich onboarder (since 0.12.0):
npx @cachely-io/sdk setup --provider prismic --tenant my-project
npx @cachely-io/sdk setup prismic --tenant my-project
npx @cachely-io/sdk init prismic --tenant my-project
What Prismic onboarding does
- Detects a Nuxt project — looks for
nuxt.config.ts,nuxt.config.js, ornuxt.config.mjs. - Detects Prismic — checks for
@prismicio/clientor@prismicio/nuxtin dependencies. - Reads
repositoryNamefromslicemachine.config.json. - Generates
composables/useCachelyPrismicClient.ts— the primary integration surface:
Use it in pages:import { createCachelyPrismicClient } from "@cachely-io/sdk/prismic" import { repositoryName } from "~/slicemachine.config.json" export function useCachelyPrismicClient() { return createCachelyPrismicClient({ repositoryName, tenant: "my-project", }) }const client = useCachelyPrismicClient(). On Nuxt 4 layouts, writes toapp/composables/instead. Picks.tsor.jsbased on existing folder contents. - On greenfield or trivially-patchable projects, also writes
app/prismic/client.js(the canonical user-defined client) and patchesconfig/nuxt/prismic.{js,ts}:// app/prismic/client.js import { createClient } from "@prismicio/client" import { createCachelyFetch } from "@cachely-io/sdk" import { repositoryName } from "~/slicemachine.config.json" const cachelyFetch = createCachelyFetch({ tenant: "my-project", provider: "prismic" }) export default createClient(repositoryName, { fetch: cachelyFetch })
With both in place,// config/nuxt/prismic.js export default { endpoint: config.repositoryName, client: "~/app/prismic/client" }usePrismic().clientis also routed through Cachely. - On complex existing clients (token, routes, custom fetch, etc.), the file is not modified. The CLI prints a loud warning + manual patch instructions instead. Re-run with
--patch-clientto force-attempt the canonical write. - Writes/merges
cachely.config.jsonin the project root:
Tooling manifest only — not a runtime import.{ "provider": "prismic", "framework": "nuxt", "repositoryName": "your-repo", "apiOrigin": "https://your-repo.cdn.prismic.io", "cachelyEndpoint": "https://my-project.cachely.io/~api/api/v2", "recommendedClient": "~/app/prismic/client", "integration": "both", "transforms": false, "experiments": false } - Installs
@cachely-io/sdkif it is not already inpackage.json. - Does not modify
nuxt.config.{ts,js}— prints the snippet to addruntimeConfig.public.cachelyProxyUrlinstead. Same policy applies to thecachely: { tenant }block when--experimentsis enabled. - Does not generate
composables/useCachely.ts— that generic helper caused confusion (generated, never called) and is no longer emitted by the Prismic onboarder. Run plainnpx @cachely-io/sdk setup(no provider) if you specifically want the lower-level fetch helper.
Integration-mode behaviour matrix
| Project state | --yes integration | Files created | Files patched |
|---|---|---|---|
| Greenfield (no canonical client) | 'both' | composable + canonical client + cachely.config.json | config/nuxt/prismic.{js,ts} (if present) |
| Existing client, trivially patchable | 'both' | composable + cachely.config.json | app/prismic/client.js (safe-patched) + config |
| Existing client, complex / custom | 'composables' | composable + cachely.config.json | none — loud warning + manual instructions printed |
In interactive mode (no --yes), you are prompted for: integration mode, transforms, experiments.
Supported flags
| Flag | Default | What it does |
|---|---|---|
--composables | (inferred — see --yes rules) | Generate the composable only. |
--patch-client | (inferred) | Write/patch the canonical app/prismic/client.js + config/nuxt/prismic. |
--composables --patch-client | (inferred) | Both. |
--no-patch-client | — | Equivalent to --composables alone. |
--transforms / --no-transforms | off | Write docs/cachely/transforms.md documenting the per-call cachely: { transform } API. |
--experiments / --no-experiments | off | Wire useCachelyExperiments() into the composable body. Print the Nuxt-module registration snippet (modules: ['@cachely-io/sdk/nuxt'], cachely: { tenant }). See Experiments. |
--custom-domain / --no-custom-domain | off | Emit customDomain: true in the client (use when the Cachely project has a custom domain with website-proxy enabled). |
--yes, --dry-run, --tenant, --proxy-url, --dir | — | Same as generic setup. |
--patch-client --experimentswithout--composablesis not recommended. The canonicalapp/prismic/client.jstemplate usescreateCachelyFetchwhich does not accept anexperimentstracker, so only the Nuxt module'sautoTrack()will work; per-response assignment-header capture requires the composable surface. The CLI prints a loud warning when this combination is requested.
Dry-run
npx @cachely-io/sdk setup --provider prismic --dry-run --tenant my-project
Prints all planned file changes without writing anything.
After Prismic onboarding
Use the generated composable in pages:
<script setup lang="ts">
const client = useCachelyPrismicClient()
const { data: page } = await useAsyncData('home', () => client.getSingle('page_home'))
</script>
If the canonical client was also written (greenfield / trivially-patchable case), const { client } = usePrismic() is routed through Cachely too. If you opted into composables-only, swap any remaining usePrismic().client callers to useCachelyPrismicClient().
Clear Nuxt's generated cache and restart:
rm -rf .nuxt
npm run dev
If the canonical client was patched, the startup log includes:
Using user-defined `client` at `~/app/prismic/client.js`
In DevTools, Prismic API requests should go to https://<tenant>.cachely.io/~api/api/v2/... and asset URLs in API JSON should be rewritten to https://<tenant>.cachely.io/<repositoryName>/....
Prismic troubleshooting
- I ran setup but requests still hit Prismic. Pages still call
usePrismic().clientor custom/api/cms/...endpoints. Switch them toconst client = useCachelyPrismicClient(). If you opted into the canonical client path, verifyconfig/nuxt/prismic.jscontainsclient: "~/app/prismic/client". useCachelyExperimentsis not defined. The Cachely Nuxt module isn't registered. Addmodules: ['@cachely-io/sdk/nuxt']andcachely: { tenant: '<slug>' }tonuxt.config.- Setup did not modify my existing client. By design — your existing client has custom options. Use the generated composable from your pages, or manually apply the printed patch instructions.
- Still seeing
cdn.prismic.io. Delete.nuxt, restart dev, and confirmconfig/nuxt/prismic.jsincludesclient: "~/app/prismic/client". - "A repository name is required..." Endpoint replacement was used in a hand-written setup. Restore
endpoint: config.repositoryNameand use the client file withcreateCachelyFetch. - Asset URLs still point at
images.prismic.io. First confirm API requests go through Cachely, then check that API response rewriting is enabled. - AI Transforms are not applying. Requests reach Cachely but come back untransformed because no transform profile was passed for that Prismic call. Pass it per-call:
The profile must be active in the dashboard (drafts only run in preview). Setclient.getSingle('page_home', { cachely: { transform: 'serbian' } })transformoncreateCachelyPrismicClient({ ... })to apply it to every call from that client; per-callcachely: { transform: null }disables the default for one request. Thecachelynamespace is stripped before params reach@prismicio/client.
Contentful onboarding
npx @cachely-io/sdk setup --provider contentful --tenant my-project
npx @cachely-io/sdk setup contentful --tenant my-project
npx @cachely-io/sdk init contentful --tenant my-project
Detects a Contentful client file under plugins/, services/, lib/, utils/, or src/{lib,services}/ and safely patches the single safe shape (one createClient(<bare-identifier>) call referencing a top-level config object with no existing adapter: key). More complex files are left untouched with manual instructions printed.
Sanity & Storyblok — detect + status-only
npx @cachely-io/sdk setup --provider sanity --tenant my-project
npx @cachely-io/sdk setup --provider storyblok --tenant my-project
These detect dependencies and metadata into cachely.config.json but do not modify any client file or install the SDK. Runtime SDK routing for these providers ships in a future release.
Manual install
If you prefer not to run the CLI:
npm install @cachely-io/sdk
# or: pnpm add @cachely-io/sdk
# or: yarn add @cachely-io/sdk
# or: bun add @cachely-io/sdk
Then write your own helper using createCachelyFetch. See the SDK reference for the full API.