Deploy · Control

Governed chat widget

Add a protected chat surface to your site. Each send is an independent governed POST /run — Boundary checks the prompt before provider inference. Use a script tag or an npm adapter; all paths share the same core.

Choose an integration

  • Script embed — fastest; load https://www.norcaster.com/chat/v1.js from a script tag.
  • npm adapters — React, Vue, or Svelte components on @norcaster/chat-*.
  • SDK / API — full control via POST /run from your backend or client SDK.

Script embed

Norcaster serves the widget at https://www.norcaster.com/chat/v1.js (built from @norcaster/chat-core).

Inline (mount in your page)

<!-- Try it live -->
<div id="norcaster-chat-root"></div>
<script
  src="https://www.norcaster.com/chat/v1.js"
  data-deployment="YOUR_DEPLOYMENT_ID"
  data-api-key="YOUR_DEPLOYMENT_KEY"
  data-mode="inline"
  data-theme="dark"
  data-greeting="Messages are checked by Norcaster before the model."
  async
></script>

Floating launcher

<script
  src="https://www.norcaster.com/chat/v1.js"
  data-deployment="YOUR_DEPLOYMENT_ID"
  data-api-key="YOUR_DEPLOYMENT_KEY"
  data-position="bottom-right"
  async
></script>

Script attributes

AttributeRequiredNotes
data-deploymenttrueDeployment id from the dashboard.
data-api-keyone of key or runUrlKey that can only run: from the deployment's Connect tab, or runs:write only. Visible to every visitor.
data-run-urlone of key or runUrlSame-origin proxy URL; session cookie auth instead of api-key.
data-api-urlfalseAPI base (default https://api.norcaster.com).
data-modefalseinline (mount in #norcaster-chat-root) or floating (default).
data-targetfalseCSS selector for inline mount (default #norcaster-chat-root).
data-positionfalsebottom-right or bottom-left (floating).
data-themefalsedark, light, or auto.
data-greetingfalseFirst line shown in the transcript.
data-providerfalseOptional gateway routing metadata.
data-modelfalseOptional gateway routing metadata.
data-lazyfalsetrue or 1 to defer init until visible.

npm packages

Framework adapters wrap @norcaster/chat-core — they do not reimplement chat logic. Published on npm under the @norcaster scope.

  • @norcaster/chat-core — Vanilla mountNorcasterChat / embed IIFE source
  • @norcaster/chat-react — React 18+ <NorcasterChat />
  • @norcaster/chat-vue — Vue 3 <NorcasterChat />
  • @norcaster/chat-svelte — Svelte 5 <NorcasterChat />

React (Next.js App Router)

pnpm add @norcaster/chat-react @norcaster/chat-core

// components/norcaster-chat.tsx
"use client";
import { NorcasterChat } from "@norcaster/chat-react";

export function NorcasterChatPanel() {
  return (
    <NorcasterChat
      deploymentId={process.env.NEXT_PUBLIC_NORCASTER_DEPLOYMENT_ID!}
      apiKey={process.env.NEXT_PUBLIC_NORCASTER_PUBLISHABLE_KEY!}
      theme="dark"
      greeting="Try a message — Norcaster checks it before the model."
    />
  );
}

Vue 3 (Nuxt)

pnpm add @norcaster/chat-vue @norcaster/chat-core vue

<script setup lang="ts">
import { NorcasterChat } from "@norcaster/chat-vue";
</script>

<template>
  <ClientOnly>
    <NorcasterChat
      deployment-id="YOUR_DEPLOYMENT_ID"
      :api-key="deploymentKey"
      theme="dark"
    />
  </ClientOnly>
</template>

Svelte 5 (SvelteKit)

pnpm add @norcaster/chat-svelte @norcaster/chat-core svelte

<script lang="ts">
  import { browser } from "$app/environment";
  import { NorcasterChat } from "@norcaster/chat-svelte";
</script>

{#if browser}
  <NorcasterChat
    deploymentId="YOUR_DEPLOYMENT_ID"
    apiKey="YOUR_DEPLOYMENT_KEY"
  />
{/if}

Shared props: deploymentId, apiKey, apiUrl, runUrl, theme, position, greeting, provider, model, mode, lazy. Adapters mount only in the browser (SSR-safe).

Keys, CORS, and security

  • Browser keys — every visitor can read a key in HTML or a client bundle, and Norcaster has no separate publishable key type. If the key must be in the page, use one that can only run requests: a key from the deployment's Connect tab (bound to that one deployment, runs:write), or a personal key with only runs:write (it can run all your deployments). Set a budget on the deployment and revoke the key if it leaks. Never embed a key with other scopes.
  • Server proxy (recommended) — set runUrl to a same-origin route that forwards to Norcaster with your server-held key or session cookie.
  • CORS — cross-origin widgets need each site origin in the API CORS_ORIGINS env var (comma-separated).
  • Transcript model — each send is one governed run; the widget does not maintain ChatGPT-style multi-turn memory in the UI today.

Portal sandbox bot protection

The public Boundary sandbox and homepage hero demo can require Cloudflare Turnstile when your portal deployment sets both NEXT_PUBLIC_TURNSTILE_SITE_KEY and TURNSTILE_SECRET_KEY. That protects Norcaster-hosted demos — not customer sites embedding the widget. Create keys in the Cloudflare dashboard → Turnstile → add widget domains (localhost, production host).

Related