> ## Documentation Index
> Fetch the complete documentation index at: https://developers.octaviatech.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Sample Codes

> Eight runnable apps that call the Octavia AI CMS with the official SDK.

Eight complete applications, one per stack, all using the official SDK for their own
language rather than raw HTTP. Each is a real project you can clone and run — none is
a fragment.

<CardGroup cols={3}>
  <Card title="React + Vite" icon="react" href="https://github.com/octaviatech/octavia-ai-cms/tree/main/examples/react-vite" arrow="true">
    TypeScript SPA with a dev-server proxy
  </Card>

  <Card title="Vue + Vite" icon="vuejs" href="https://github.com/octaviatech/octavia-ai-cms/tree/main/examples/vue-vite" arrow="true">
    Composition API, same proxy pattern
  </Card>

  <Card title="Next.js" icon="nextjs" href="https://github.com/octaviatech/octavia-ai-cms/tree/main/examples/nextjs-app-router" arrow="true">
    App Router Route Handlers
  </Card>

  <Card title="Nuxt 3" icon="nuxt" href="https://github.com/octaviatech/octavia-ai-cms/tree/main/examples/nuxt" arrow="true">
    Server routes keep the key server-side
  </Card>

  <Card title="Angular" icon="angular" href="https://github.com/octaviatech/octavia-ai-cms/tree/main/examples/angular" arrow="true">
    Signals and a standalone Node proxy
  </Card>

  <Card title="Laravel" icon="php" href="https://github.com/octaviatech/octavia-ai-cms/tree/main/examples/php-laravel" arrow="true">
    PHP SDK behind a controller and Blade
  </Card>

  <Card title="Go Fiber" icon="go" href="https://github.com/octaviatech/octavia-ai-cms/tree/main/examples/go-fiber" arrow="true">
    Backend only, no frontend
  </Card>

  <Card title=".NET Web API" icon="circle-dashed" href="https://github.com/octaviatech/octavia-ai-cms/tree/main/examples/dotnet-webapi" arrow="true">
    Minimal API with Swagger
  </Card>
</CardGroup>

***

## What every example does

The same sequence, so you can compare them side by side:

1. Create or read a **language**
2. Create or read an **author** and a **category**
3. **Create an article**, list articles, and set `isPublished` to publish
4. Load a **form** and **submit** an answer to it
5. Call `ai.summarize` and `report.getStatistics`

<Note>
  No example calls the REST API directly. Each uses the official SDK for its own
  language, and each sends exactly one header: <code>x-api-key</code>.
</Note>

***

## The API key never reaches the browser

Every full-stack example puts the key on a server and has the browser call its own
backend. This is not a style preference: a Vite or Next build inlines
`import.meta.env.*` into the shipped JavaScript, so a key referenced from a component
is readable by every visitor.

The pattern in each:

| Layer        | What it does                                               |
| ------------ | ---------------------------------------------------------- |
| Browser/UI   | Calls its own origin, e.g. `/api/octavia/articles`         |
| Server route | Reads `OCTAVIA_API_KEY`, calls the SDK, returns plain JSON |
| SDK          | Sends `x-api-key` and unwraps the envelope                 |

<Tabs>
  <Tab title="React / Vue / Angular">
    A Vite dev-server plugin, or a standalone Node server for Angular, mounts a
    middleware under `/api/octavia/*`. It is the only code that reads the key.
  </Tab>

  <Tab title="Next.js">
    Route Handlers under `app/api/octavia/*`. The SDK client is built lazily, so
    `next build` works on a machine with no key.
  </Tab>

  <Tab title="Nuxt">
    Server routes under `server/api/*`. The key stays in `server/utils`.
  </Tab>

  <Tab title="Laravel">
    A controller reads the key from config. The Blade page only posts to routes.
  </Tab>
</Tabs>

<Warning>
  In the Vite examples the proxy is dev-only. A production deploy must put an
  equivalent server-side route in front of the built bundle — serving the static
  build alone renders the UI but every API call 404s. Each README says so explicitly.
</Warning>

***

## Running one

```bash theme={null}
git clone https://github.com/octaviatech/octavia-ai-cms.git
cd octavia-ai-cms/examples/nextjs-app-router
npm install
npm run dev
```

You need three values, from your [dashboard](https://dashboard.octaviatech.app):

| **Variable**          | **What it is**                    |
| --------------------- | --------------------------------- |
| `OCTAVIA_API_KEY`     | Your API key                      |
| `OCTAVIA_CATEGORY_ID` | A category to file articles under |
| `OCTAVIA_AUTHOR_ID`   | An author to attribute them to    |

<Note>
  The dependency order matters. An article cannot be created before the language,
  author and category exist — see
  <a href="/api-reference/ai-cms/quickstart">Quickstart</a>.
</Note>

***

## Working in these projects with an agent

The repository ships the <a href="/api-reference/ai-cms/sdks/skill">agent skill</a> at
`.claude/skills/octavia-cms/`, so cloning it installs the skill and the examples
together:

```bash theme={null}
git clone https://github.com/octaviatech/octavia-ai-cms.git
cd octavia-ai-cms
```

An agent working in that checkout has both the rules and eight working references to
check its output against. See
<a href="/api-reference/ai-cms/sdks/llm-agents">Using these files</a> for the full
install guide.

***

## Two things the examples get right that are easy to miss

**Forms are fetched by id, not listed.** `form.getAll` returns only a submissions
count per form — no id, title or slug — so it cannot drive a picker. Every example
takes a form id as input and calls `form.getById`.

**Publishing is a field update.** There is no publish endpoint. `article.update` with
`isPublished: true` publishes; `archive` is a soft delete, and `delete` is the real
remove.

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/api-reference/ai-cms/quickstart" arrow="true">
    The same sequence as plain HTTP
  </Card>

  <Card title="SDKs" icon="box" href="/api-reference/ai-cms/sdks/overview" arrow="true">
    Per-language reference
  </Card>
</CardGroup>
