Plugins

AI assistant

The official ai plugin (paid) puts AI to work on three everyday jobs of a website: writing and SEO in the editor, translating content into every site language in one click, and answering visitors' questions on the site. It ships with the framework (plugins/ai).

node node_modules/nuxtcms/scripts/plugin.mjs add ai
pnpm build:cf && pnpm deploy

Providers

Choose the provider and enter the API key under Admin → Plugins → AI assistant → Configure (or set NUXT_AI_API_KEY, NUXT_AI_BASE_URL, NUXT_AI_MODEL):

ProviderDefault modelNotes
DeepSeekdeepseek-chatReachable from mainland China, good value
Qwen (Alibaba Cloud Model Studio)qwen-plusDashScope compatible mode
OpenAIgpt-4o-mini
Kimi (Moonshot)moonshot-v1-8k
Zhipu GLMglm-4-flash
Other OpenAI-compatible APIyour choiceOpenRouter, Ollama, a company gateway... with its base URL
Cloudflare Workers AI@cf/meta/llama-3.1-8b-instructOn Cloudflare bind AI (wrangler: [ai] binding = "AI"), elsewhere enter the account ID and an API token

Admin → AI assistant tests the connection and shows calls and tokens of the last 30 days by feature. The API key never appears in pages, logs or answers.

Writing and SEO in the editor

Post, page and product editors get an "AI assistant" panel:

  • Suggest SEO: SEO title, description, excerpt, focus keyword, tags and slug, applied one by one or all at once (an existing slug is kept, so URLs do not change).
  • Title ideas: five titles, one click to use one.
  • Writing: draft from the title, continue, rewrite, polish, shorten, expand; preview first, then replace the content or append.

Suggestions only fill the form; nothing changes until you save.

One-click translation

Pick the languages in the panel and click "Translate": each language gets a draft with the same slug to check before publishing. When a language version exists you are asked before it is replaced; a revision is saved first (restore it from the revision history) and its status is kept. Links, images and the HTML structure stay as they are; long content is translated piece by piece. HTML from the model is always sanitized before it is stored.

Q&A on the site

With the Q&A switched on, a button at the bottom left opens a chat that answers from the site's published posts, pages and products, with links to the pages it used. When the content has no answer it says so and suggests contacting you; it never invents prices or specifications.

  • Questions per visitor and day are configurable (default 20), plus a per-minute limit.
  • "Extra instructions" can hold contact details or a tone of voice.
  • With "credits per question" above 0 the SaaS kit is needed: visitors sign in, and credits are taken only for a delivered answer (recorded in their credit history).
  • Hide or reorder it in the site's app.config.ts: nuxtcms: { slots: { 'app:end': { AiChatWidget: false } } }.

In your own APIs

export default defineEventHandler(async (event) => {
  const cfg = await requireAi(event)
  const user = await requireSaasApiUser(event)          // with the SaaS kit
  await spendSaasCredits(event, user.id, 1, 'ai.summary')
  const r = await aiChat(event, cfg, {
    feature: 'assist',
    actor: `user:${user.id}`,
    messages: [{ role: 'user', content: 'Summarize in one sentence: ...' }],
  })
  return { text: r.text }
})

The table {prefix}ai_usage is created on first use.

Testing

pnpm smoke:ai --base http://localhost:3192 --db .data/saas-demo.sqlite starts a fake OpenAI-compatible server and covers the connection test, SEO, writing (hostile output sanitized), translation (drafts, overwrite prompt, revisions, links kept), the Q&A (search, sources, daily limit, credit charges) and provider errors, without a real key.