Skip to main content

Documentation

No results found.
Features

AI Snippet Generation

WebProCMS lets administrators generate HTML, JavaScript, or PHP snippets directly from the Snippets dashboard using whichever LLM provider they've configured. Describe what the snippet should do — the AI writes the code, and you save it as...

Bring-your-own API key. Operators configure their own provider key (Anthropic Claude, OpenAI, Google Gemini, or DeepSeek) on the API Keys settings page; per-call generation costs are billed by the provider, not by WebProCMS. No membership required.

WebProCMS lets administrators generate HTML, JavaScript, or PHP snippets directly from the Snippets dashboard using whichever LLM provider they've configured. Describe what the snippet should do — the AI writes the code, and you save it as an inactive snippet to review before it goes live.


The problem

Snippets are how editors bolt third-party tags onto a CMS site without touching templates — analytics, conversion pixels, chat widgets, schema markup, custom meta tags. The friction isn't the editor; it's tracking down the exact tag the vendor expects, copying it without typos, and remembering whether it belongs in <head> or before </body>.

For the everyday cases — "Add a GA4 script", "Add an Open Graph image meta tag", "Set up a Meta Pixel" — the snippet is well-known, the editor doesn't need a senior engineer to write it, and the cost of pausing the workflow to look it up is the only real friction.

The fix

The Snippets dashboard has a "Generate Snippet" button next to "New Snippet". It opens a modal with three inputs:

  1. Name — what to call the snippet (e.g. "Google Analytics 4").
  2. Type — HTML, JavaScript, or PHP.
  3. Prompt — a sentence describing what the snippet should do.

Click Generate and the configured LLM returns the code. Review (and edit) the result in the modal's textarea, then click Save Snippet. The new record is created inactive so nothing changes on the public site until you click the activation badge.

Provider configuration

The generation call routes through App\Support\AiTextService::generate(...) with the TASK_CODE task constant. Resolution order:

  1. ai.code_provider (if set in Settings → API Keys → "Code generation override") — the provider that handles Tailwind class generation in the page editor also handles snippet generation.
  2. ai.text_provider (fallback) — the default text provider for the install.

API keys are resolved per-provider — ai.claude_key, ai.openai_key, ai.google_key, ai.deepseek_key. If the resolved provider has no key, generation surfaces a clear error inline (e.g. "Claude API key is not set in Settings → API Keys (selected for the 'code' task).") rather than failing silently.

If no provider is configured at all, the error reads "No AI text provider configured. Choose one in Settings → API Keys."

Type-aware prompts

Each type uses a system prompt tuned to produce code that's safe to drop straight into a snippet record:

Type System prompt shape
html "You generate HTML snippets for injection into a public web page (typically inside the <head> or just before </body>). Return only raw HTML — do not include markdown code fences, language tags, comments explaining the response, or any preamble. You may include <script>, <link>, <style>, <meta>, or <noscript> tags as appropriate for the request."
js "You generate JavaScript snippets for injection into a public web page. Return only raw JavaScript — do not include <script> tags, markdown code fences, comments explaining the response, or any preamble. The code must be safe to inject inline and run in a modern browser without a build step."
php "You generate PHP snippets for execution at the top of a Laravel Blade page before any output. Return only raw PHP code — do not include opening or closing PHP tags, markdown code fences, comments explaining the response, or any preamble. Assume the Laravel app context is available (helpers like request(), session(), auth() work). Do not echo output; assign to variables that the page can use."

Even when the model ignores the "no fences" rule and wraps its response in a ```html block, the result is stripped before it reaches the textarea so the saved snippet stays clean.

Placement is auto-derived from type

When the snippet is saved, its placement is set automatically from the type via SnippetType::defaultPlacement():

Type Default placement
html Head (before </head>)
js Scripts (before </body>)
php PHP (top of page)

You can change the placement from the snippet's edit page if the default doesn't fit the use case (e.g. an HTML snippet that needs to render at the bottom of the body).

AI-generated snippets save with consent_category = necessary. If you're enabling Cookie Consent and the snippet is an analytics or marketing tag, change the category on the edit page before activating — necessary snippets always run, including before the visitor grants consent. See Cookie Consent for the full consent flow.

Save is always inactive

The save handler hardcodes is_active = false on every generated snippet so the public site never picks up unreviewed AI output. The list page shows the new record with a grey "Inactive" badge; clicking the badge toggles it to active.

This is the same review workflow used by the rest of the AI features (image generation saves to the media library, alt-text generation populates a field but doesn't auto-confirm) — the editor is always the final approver.

What lives where

Path Purpose
resources/views/pages/dashboard/snippets/⚡index.blade.php Hosts the "Generate Snippet" button, the generate modal, and the Livewire methods (openGenerateModal, generateSnippet, saveGeneratedSnippet, discardGeneratedSnippet).
app/Support/Ai/AiTextService.php The provider router. Single entry point for every text-completion call in the app; honours ai.code_provider / ai.code_model overrides via the TASK_CODE constant.
app/Models/Snippet.php The Eloquent model. Caching, response-cache invalidation, and forPage() scope all run unchanged whether the snippet came from AI or was typed by hand.

Settings reference

Key Default Notes
ai.code_provider '' Optional per-task override. One of claude, openai, google, deepseek. Empty means "use ai.text_provider".
ai.code_model '' Optional per-task model override. Empty means "use the resolved provider's default model (ai.{provider}_model)".
ai.text_provider '' Fallback text provider when ai.code_provider is empty.
ai.claude_key / ai.openai_key / ai.google_key / ai.deepseek_key '' Per-provider API keys. The resolved provider's key is required; missing keys surface a clear inline error.