# Strife developer documentation Source: https://strife.app/docs This is the home of the Strife documentation.
TutorialsStart here! The tutorials will get you started with Strife in no time.getting-started
How-to GuidesStep-by-step guides showing how to achieve common tasks in Strifehow-to-overview.md
ReferenceThe gory details about Strife's SDKs, APIs and configurationreference-overview.md
ExplanationDiscussions and deep dives into key topics of Strifeexplanation-overview.md
--- # Getting started Source: https://strife.app/docs/tutorials/getting-started Connect to the Strife API and interact with your data in a few steps: To help you get started, we offer two quick start guides tailored to your preferred development environment. If you’re working with JavaScript, check out our **Node.js Getting Started** guide to set up your environment and run your first application. Prefer C#? Our **.NET Getting Started** guide walks you through installation, configuration, and building your first project. **Choose the path that fits your background and start building today:** - [Node.js](https://strife.app/docs/tutorials/getting-started/nodejs.md) - [.NET](https://strife.app/docs/tutorials/getting-started/dotnet.md) --- # Node.js Source: https://strife.app/docs/tutorials/getting-started/nodejs Connect to the Strife API and interact with your data in a few steps: ### 1. Install Strife SDK ```bash npm i @strifeapp/strife ravendb ``` ### 2. Create and initialize a Strife store > [!NOTE] > The environment settings were provided during onboarding. ```js import { DocumentStore } from 'ravendb'; const certificate = import.meta.env.STRIFE_CERTIFICATE; let authOptions = { certificate: Buffer.from(certificate, 'base64'), type: 'pfx', password: import.meta.env.STRIFE_CERTIFICATE_PASSWORD, }; const store = new DocumentStore( import.meta.env.STRIFE_DATABASE_URLS.split(','), import.meta.env.STRIFE_DATABASE, authOptions ); export default store.initialize(); ``` ### 3. Define a Collection A [Collection](https://ravendb.net/docs/article-page/7.0/csharp/client-api/faq/what-is-a-collection) is a group of records, called Documents, that all share a common schema. You can define as many Collections as your application needs. Each Document in a Collection is stored in the Database based on the [Fields](https://strife.app/docs/reference/fields.md) that you define, and is automatically queryable using a [Document session](https://ravendb.net/docs/article-page/7.0/nodejs/client-api/session/what-is-a-session-and-how-does-it-work). > [!NOTE] > A Collection in Strife should not confused with a Collection in RavenDB ```json { "collection": "Articles", "fields": [ { "label": "Heading", "editor": { "name": "str-input", "propertyName": "heading", }, } ] } ``` ### 4. Query your pages Using async await syntax: ```js import store from '@/store/index'; const session = store.openSession(); let page = await session .query({ indexName: 'Content/ByUrl' }) q .whereEquals('url', '/about') .firstOrNull(); console.log(`Found page with ${page.heading}`); ``` Or promises: ```js session.query({ collection: "Articles" }) .all() .then((articles) => { if(articles.length) { articles.map(article => console.log(`${article.displayName} was published: ${article.publishedAt}`)); } else { console.log('No articles found'); } }); ``` ### 5. Query your Media Using promises: ```javascript await session.query({ collection: 'Files'}) .whereEquals('mimeType', 'video/mp4') .all() .then(files => { if(files.length) { files.map(file => console.log(`${file.name} with size: ${file.size}`)); } else { console.log('No files found'); } }); ``` ### Search your Content Using promises: ```javascript await session.query({ indexName: "Content/FulltextSearch" }) .search('fields', params.query) .orderByScore() .skip((params.page - 1) * PAGE_SIZE) .take(PAGE_SIZE) .all() .then(hits => { if(hits.length) { hits.map(hit => console.log(`${hit.displayName}`)); } else { console.log('No hits'); } }); ``` ### 6. Setup Real time preview Use in web component by subscribing to the Strife studio's events and call the provided callback function. ```js import { subscribe } from '@strifeapp/strife'; export default class Sections extends LitElement { static properties = { sections: { type: Array }, }; firstUpdated() { // Subscribe to Live Preview events using the`subscribe` function this.unsubscribe = subscribe((data) => { this.sections = data.sections; }); } disconnectedCallback() { super.disconnectedCallback(); this.unsubscribe(); } render() { return repeat(this.sections, (item) => item.id, (item, index) => {…}); } } ``` --- # .NET Source: https://strife.app/docs/tutorials/getting-started/dotnet Connect to the Strife API and interact with your data in a few steps: ### 1. Install Strife SDK ```bash dotnet add package strife ``` ### 2. Initialize Strife > [!NOTE] > The environment settings were provided during onboarding. ```json title="appsettings.json" { "DocumentStoreSettings": { "Urls": "", "Database": "", "Certificate": "", "Password": "" }, "Strife": { "Secret": "", "Workspace": "", "StartId": "" } } ``` ```csharp title="Program.cs" using Strife; using Strife.Routing; var builder = WebApplication.CreateBuilder(args); builder.Services.AddStrife(); var app = builder.Build(); app.UseRouting(); app.MapStrife(); app.Run(); ``` ### 3. Define a Collection and Template A [Collection](https://ravendb.net/docs/article-page/7.0/csharp/client-api/faq/what-is-a-collection) is a group of records, called Documents, that all snapshot a common schema. You can define as many Collections as your application needs. Each Document in a Collection is stored in the Database based on the [Fields](https://strife.app/docs/reference/fields.md) that you define, and is automatically queryable using a [Document session](https://ravendb.net/docs/article-page/7.0/nodejs/client-api/session/what-is-a-session-and-how-does-it-work). Use the **Template Builder** in Strife Studio to define Collections and their templates. Then, create a corresponding C# model to represent your Collection in code. > [!NOTE] > A Collection in Strife should not confused with a Collection in RavenDB ```csharp using Strife.Models; public record BlogPost : Content { public string Heading { get; set; } public string Body { get;set; } } ``` ### 4. Rendering Content When using the Strife SDK, content models are automatically resolved and passed to your controller actions without any manual fetching or lookup. Here's a typical example using an `BlogPostController`. ```csharp using Microsoft.AspNetCore.Mvc; using Strife.Binding; public class BlogPostController : Controller { public IActionResult Index([FromContentRoute] BlogPost content) { return View(content); } } ``` #### How It Works * **Automatic Content Binding**:\ By using the `[FromContentRoute]` attribute, Strife automatically resolves and injects the correct `BlogPost` content based on the current route. You don't need to query for the content manually — it's handled for you. * **Model-Driven Views**:\ The resolved `BlogPost` instance is passed directly to the view, making it easy to render content using a strongly typed model. * **Routing Integration**:\ The system maps the incoming route to a specific content item (Document) and ensures that the correct type (e.g., BlogPost) is provided to your action. Here’s a simplified example of how you might use the `BlogPost` model in a Razor view: ```cshtml @model BlogPost

@Model.Heading

@Model.Body
``` By using `[FromContentRoute]`, you can focus on building views and logic without worrying about content retrieval. Strife takes care of resolving the right content based on the route and passing it into your controller actions. ### 5. Setup Real time preview To enable real-time preview and connect your site to **Strife Studio**, include the Strife JavaScript SDK in your project. Add the following to your HTML: ```html ``` Once connected, you can enable **Live Preview** in two ways: * [**Using Strife Web Components**](https://strife.app/docs/reference/live-preview/web-components.md) for quick integration. * [**Building a custom live preview implementation**](https://strife.app/docs/reference/live-preview/custom-live-preview-implementation.md) if you need more control over the preview experience. This setup ensures that content editors can see real-time updates directly on the site as they work in Strife Studio. #### Snapshots (optional) Editors can hand a reviewer without a Strife account a **preview link** — `https://example.com/snapshot/{token}` — that shows a frozen, unpublished version of a document on your site for 7 days. Nothing to register: `MapStrife()` resolves the route, your controller receives the snapshot through `[FromContentRoute]` as usual, and `ContextService.GetSnapshot(HttpContext)` tells you when you are rendering one: ```csharp var snapshot = _context.GetSnapshot(HttpContext); // Strife.Services.SnapshotContext, or null if (snapshot != null) { // show a preview notice with snapshot.Name (render as text) and snapshot.ExpiresAt; // skip analytics and Open Graph tags } ``` Expired, revoked or unknown links are your site's ordinary not-found. The route needs a `Content/ByUrl` index built from the `@strifeapp/strife` release that ships snapshots (run `strife push` after updating). Locale handling, the headers the SDK sets, and the CDN/analytics rules are in the [Snapshots](https://strife.app/docs/reference/snapshots.md) reference. ### 6. Querying and Searching To **query** or **search** for documents, use the RavenDB client provided by the SDK. The `IDocumentStore` is available via **dependency injection** in your controllers and services. Here’s an example of querying related documents in a controller: ```csharp using Microsoft.AspNetCore.Mvc; using Strife.Binding; public class BlogListController : Controller { private readonly IDocumentStore _store; public BlogListController(IDocumentStore store) { _store = store; } public IActionResult Index([FromContentRoute] BlogList content) { var viewModel = new BlogListViewModel(content); using (var session = _documentStore.OpenAsyncSession()) { viewModel.CurrentPosts = await session.Query(content.Posts); } return View(viewModel); } }. ``` > [!NOTE] > `content.Posts` is assumed to be a list of BlogPost IDs stored in the `BlogList` document. > > Use `LoadAsync()` when loading specific documents by ID, and `Query()` for broader queries. #### Full-Text Search Example For more advanced search scenarios, such as full-text search with highlighting and scoring, you can query an index like this: ```csharp var hits = await session.Query() .Search(x => x.SearchText, query, @operator: SearchOperator.And) .Highlight(x => x.SearchText, 100, 1, highlightingOptions, out Highlightings highlights) .OrderByScore() .Skip((page - 1) * pageSize) .Take(pageSize) .ProjectInto() .Statistics(out QueryStatistics stats) .ToArrayAsync(); ``` > [!NOTE] > **Note:** A **full-text search index** (e.g., `Content_FullTextSearch`) **must be created manually** in RavenDB. Strife does **not** provide built-in search indexes — this allows you to define custom indexing logic suited to your content. ### Additional Resources For more details on querying, indexing, and advanced search capabilities, see the [RavenDB official documentation](https://ravendb.net/docs/article-page/6.2/csharp/start/getting-started). --- # Astro Source: https://strife.app/docs/tutorials/astro Build fast, flexible, and CMS-powered websites with Strife and Astro. ## Getting Started with Strife and Astro This guide walks you through how to integrate Strife CMS into your Astro project using TypeScript. > [!NOTE] > **There's a newer, code-first alternative to steps 3–4 and 9 below.** [Strife CLI](https://strife.app/docs/reference/cli.md) lets you define templates with [`defineType`](https://strife.app/docs/reference/cli/schemas.md) instead of hand-written `Template` objects registered via the integration's `collections` option, and deploys them explicitly with `strife push` rather than lazily on first request. The Template-object approach on this page still works and isn't being removed, but `defineType` + `strife push` is the recommended path for new projects — see the [CLI reference](https://strife.app/docs/reference/cli.md) for the full picture, including [how credentials are provisioned automatically](https://strife.app/docs/reference/cli.md#bootstrapping-a-brand-new-project) instead of the six manual `.env` values in step 6. *** ### 1. Create a new Astro project Start by creating a fresh Astro project: ```bash npm create astro@latest ``` Follow the prompts to scaffold your site. *** ### 2. Install the Strife Astro Integration Inside your Astro project, install the Strife integration: ```bash npx astro add @strifeapp/astro ``` After running this, your `astro.config.mjs` will be updated automatically: ```javascript import { defineConfig } from 'astro/config'; import strife from '@strifeapp/astro'; export default defineConfig({ integrations: [strife()], output: 'server', }); ``` Strife requires `output: 'server'` because content is fetched at request time. The integration sets this automatically on install, and also pulls in `@strifeapp/types` so TypeScript users get full type safety without any extra install step. From `@strifeapp/astro` 1.6.0 the integration caps the RavenDB client's in-memory response cache at 8 MiB (set `strife({ httpCache: { maxBytes } })` to change it). If your project also lists `ravendb` as its own dependency, keep it at 7.2.3 or later: older clients cannot be given a byte budget, so the integration limits them to 500 cached responses and logs a warning. > [!WARNING] > **Using an older version of the integration?** Until the updated Astro plugin ships, three things need to be done manually: > > 1. **Install types manually** if `astro add` doesn't include them automatically: > > ```bash > npm install -D @strifeapp/types > ``` > 2. **Add `output: 'server'`** to your `defineConfig({ ... })` call if it's missing after `astro add`. > 3. **Add a `name` field** to every Template, matching its `collection` value (e.g. `name: 'Homes'` on the Homes template in the next step). Without it, all templates silently collide at the same storage key and only the last registered one survives. > > Once the new plugin version lands, all three are handled for you and these steps aren't needed. *** ### 3. Define your first Collection and Template In Strife, content is structured via **Collections** and **Templates**. Each template describes the fields available for a collection item. A typical site has a mix of **singleton** templates (one document per project — e.g. a Home page or Global Settings) and **multi-instance** templates (many documents — e.g. blog posts or product pages). Strife controls this with the `composable` field on the template. > For more information on how templates and collections work, see the full [Strife Templates & Collections documentation](https://strife.app/docs/reference/templates.md). > [!NOTE] > **A quick note on "collections":** Strife uses the word "collections" in two places — the `collections` array on the `strife()` integration (the list of templates to register, see step 4) and the `collection` field on each Template (the RavenDB document collection name). Neither is related to Astro's native [content collections](https://docs.astro.build/en/guides/content-collections/) feature (configured via `src/content/` and `content.config.ts`). If you see a `Content config not loaded` warning at boot, that's Astro noticing you haven't set up its own content collections — it's safe to ignore if you're using Strife exclusively. Start with a Home template for your site's root page. Create `src/collections/Home.ts`: ```typescript import { type Template } from '@strifeapp/types'; const Home: Template = { displayName: 'Home', collection: 'Homes', templateType: 'dt', normalizedName: 'home', composable: false, // singleton — only one Home document per project editors: [ { label: 'Heading', editor: { name: 'str-input', type: 'text', propertyName: 'heading' }, }, { label: 'Description', editor: { name: 'str-textarea', type: 'text', propertyName: 'description' }, }, ], }; export default Home; ``` Then add a Pages template for any other content — about, contact, marketing pages, anything that isn't a one-off. Create `src/collections/Pages.ts`: ```typescript import { type Template } from '@strifeapp/types'; const Pages: Template = { displayName: 'Page', collection: 'Pages', templateType: 'dt', normalizedName: 'page', composable: true, // multi-instance — editors can create many Pages editors: [ { label: 'Heading', editor: { name: 'str-input', type: 'text', propertyName: 'heading' }, }, { label: 'Description', editor: { name: 'str-textarea', type: 'text', propertyName: 'description' }, }, ], }; export default Pages; ``` The two templates illustrate the contrast: `Home` has `composable: false` (only one document allowed), while `Pages` has `composable: true` (editors can create many). Use `composable: false` for templates that should only ever have one document — Home, Global Settings, Footer config, etc. — and `composable: true` for repeatable content. See the templates reference for the full list of template properties. > [!WARNING] > **Singleton seeding:** for templates with `composable: false`, the single document needs to exist before your site can render it. Open Strife Studio → your team → Content, create a new Home document, and set its `url` to `/`. > > Future Strife versions auto-provision the root Home document when a team is created — so this specific step disappears. Other singleton templates you add later (Global Settings, Footer, etc.) follow the same manual-seed pattern and aren't auto-provisioned. *** ### 4. Register your Collection Import your collection and register it in your Strife integration at `astro.config.mjs` ```javascript import { defineConfig } from 'astro/config'; import strife from '@strifeapp/astro'; import Home from './src/collections/Home'; import Pages from './src/collections/Pages'; export default defineConfig({ integrations: [strife({ collections: [Home, Pages] })], output: 'server', }); ``` *** ### 5. Create your Content Types Define TypeScript interfaces matching each collection for strong typing when querying: ```typescript import { type Content } from '@strifeapp/types'; export type Home = Content & { heading: string; description: string; }; export type Page = Content & { heading: string; description: string; }; ``` In real projects these two might diverge — Home could have its own hero structure, Pages might be more flexible — but for the tutorial they share the same shape. *** ### 6. Add your Strife Credentials Create a `.env` file in your project root with the credentials provided for your team: ```bash # .env # RavenDB client certificate — base64-encoded PFX bundle STRIFE_CERTIFICATE=... # Password protecting the PFX certificate above STRIFE_CERTIFICATE_PASSWORD=... # Comma-separated list of RavenDB node URLs STRIFE_DATABASE_URLS=https://a.example.strife.ravendb.cloud # Name of your team's RavenDB database STRIFE_DATABASE=... # Your team's unique identifier TEAM_ID=... # Signing secret used for preview and webhook payloads SECRET=... ``` > [!NOTE] > These six values are provided during your Strife onboarding. The same cert-based authentication model is used by the Node.js SDK — if you've set that up before, the values are the same. > > If you're using [Strife CLI](https://strife.app/docs/reference/cli.md) (`npx strife` / `strife .`), you won't need to set these six individually — the CLI packs the same information into a single `STRIFE_SECRET` value and writes it to `.env` for you. Both forms are read by the integration; use whichever your provisioning path gave you. > [!WARNING] > Treat every value above as a secret. Never commit `.env` to version control — add it to `.gitignore` if `npm create astro@latest` didn't do so already. *** ### 7. Enable TypeScript Module Declarations To support type-safe access to Strife's document store, update or create `src/env.d.ts` (recent Astro starters auto-generate types in `.astro/` and don't ship a stub `env.d.ts`): ```typescript /// declare module 'strife:store' { import type { IDocumentSession, IDocumentStore } from 'ravendb'; export const store: IDocumentStore; export { IDocumentSession }; } ``` *** ### 8. Query Content from Strife You can now query your content directly from RavenDB via Strife. The same query pattern works for both singleton and multi-instance templates — it matches by URL: ```typescript import { store } from 'strife:store'; import type { Home } from '../collections/Home'; const session: IDocumentSession = store.openSession(); // Returns the Home document for url='/'. // For other URLs ('/about', '/contact', etc.), the same query returns // whichever Page document has that url. const home: Home = (await session .query({ indexName: 'Content/ByUrl' }) .whereEquals('url', '/') .selectFields(['heading', 'description']) .firstOrNull()) as Home; ``` *** #### 9. Deploy your templates > [!WARNING] > Earlier versions of the integration deployed templates and the content index automatically, on the first request to a route that imported `strife:store`. That's no longer the case — the integration only connects to the database and reads content now. Deployment is explicit, via the CLI, as described below. Templates and the `Content/ByUrl` query index are deployed with [Strife CLI](https://strife.app/docs/reference/cli.md): ```bash npm install --save-dev @strifeapp/cli @strifeapp/strife npx strife login npx strife link ``` The templates you registered as `Template` objects in step 4 aren't picked up by `strife push` directly — `push` deploys schemas written with [`defineType`](https://strife.app/docs/reference/cli/schemas.md). If you're following this tutorial's `Template`-object approach, create your templates directly in Strife Studio instead (Settings → Templates) rather than via `push`, or see the [CLI reference](https://strife.app/docs/reference/cli.md) for defining them in code as `defineType` schemas instead of the `Template` objects used in steps 3–4. Once your templates exist (via Studio or `defineType` + `push`), start the dev server as usual: ```bash npm run dev ``` and visit the URL Astro prints (e.g. `http://localhost:4321/`). *** #### 10. Add live preview (optional) Strife Studio includes a preview iframe that mirrors your site as content is edited. With the integration installed, your islands can subscribe to updates: ```svelte

{data.heading}

{data.description}

``` This requires loading `@strifeapp/strife` eagerly in your root layout (otherwise the iframe handshake completes before subscribers are ready). For full setup, the data-shape reference, and framework-agnostic patterns, see [Custom Live Preview implementation](https://strife.app/docs/reference/live-preview/custom-live-preview-implementation.md). *** #### Snapshots (optional) Editors can hand a reviewer without a Strife account a **preview link** — `https://example.com/snapshot/{token}` — that shows a frozen, unpublished version of a document on your site for 7 days. The integration's snapshot middleware resolves the link; you add the page that renders it. Add `src/pages/snapshot/[token].astro`. A minimal version is below; the complete template, with the rules a snapshot page must follow, is in the [Snapshots](https://strife.app/docs/reference/snapshots.md) reference. ```astro --- export const prerender = false; // rendered on demand — never prebuilt import Layout from '../../layouts/Layout.astro'; const { name, expiresAt, locale, content } = Astro.locals.snapshot!; ---

{content.heading}

``` Expired, revoked or unknown links render your 404 page. The route needs a `Content/ByUrl` index built from the `@strifeapp/strife` release that ships snapshots (run `strife push` after updating), and the name must be rendered as text only. Locale prefixes, `snapshot.fields`, sites that resolve locale in their own middleware, and the CDN/analytics rules are in the [Snapshots](https://strife.app/docs/reference/snapshots.md) reference. *** ### 11. Choose a deployment adapter `astro dev` works out of the box. For production builds (`astro build`), Astro needs an adapter that matches your deploy target. Strife doesn't require a specific one — pick whichever suits your hosting: | Deploy target | Adapter | Install | | ------------------- | --------------------- | -------------------------- | | Self-hosted Node.js | `@astrojs/node` | `npx astro add node` | | Vercel | `@astrojs/vercel` | `npx astro add vercel` | | Netlify | `@astrojs/netlify` | `npx astro add netlify` | | Cloudflare Workers | `@astrojs/cloudflare` | `npx astro add cloudflare` | See [Astro's deploy guides](https://docs.astro.build/en/guides/deploy/) for the full list and configuration details. After installing an adapter, your `astro.config.mjs` will look something like: ```javascript import { defineConfig } from 'astro/config'; import strife from '@strifeapp/astro'; import node from '@astrojs/node'; // or vercel, netlify, cloudflare… import Homes from './src/collections/Homes'; export default defineConfig({ integrations: [strife({ collections: [Homes] })], output: 'server', adapter: node({ mode: 'standalone' }), // adapter-specific options vary }); ``` Push your repository to your chosen host and your Strife-powered Astro site is live. --- # Quickstart Source: https://strife.app/docs/tutorials/quickstart Easy as 1, 2, 3! --- # Next.js Source: https://strife.app/docs/tutorials/next.js Build an application using Next.JS and Strife ### Prerequisites > [!WARNING] > Before you read any further, make sure that you have a valid invite and received the welcome email. Before you begin, ensure you have the following: * A package manager (NPM) * A [Next.js](https://nextjs.org/docs/getting-started/installation) app ### Installation First, install the RavenDB Node.js client using NPM: ```bash title=">_ Terminal" npm install ravendb --save ``` ### Configuration Add your RavenDB database configuration to the `.env.local` file in your Next.js app: > [!NOTE] > You may need to create `.env.local` if it does not exist. ```sh title=".env.local" STRIFE_CERTIFICATE=xxx STRIFE_CERTIFICATE_PASSWORD=xxx STRIFE_DATABASE_URLS=xxx STRIFE_DATABASE=xxx ``` ### Create your first query To request the home page based on the URL, create a query using the RavenDB Node.js client: > [!NOTE] > This query uses a predefined index called `Content/ByUrl`. The index is used to query content based on a relative URL. ```javascript title="src/app/page.js" import { DocumentStore } from 'ravendb'; const certificate = process.env.STRIFE_CERTIFICATE; const authOptions = { certificate: Buffer.from(certificate, 'base64'), type: 'pfx', password: process.env.STRIFE_CERTIFICATE_PASSWORD, }; const store = new DocumentStore( process.env.STRIFE_DATABASE_URLS.split(', '), process.env.STRIFE_DATABASE, authOptions ); store.initialize(); const session = store.openSession(); const query = session .query({ indexName: 'Content/ByUrl' }) .whereEquals('url', '/'); const home = await query.firstOrNull(); ``` ### Real-Time Preview #### Prepare the App for Real-Time Updates Include the Strife JavaScript SDK using the [Script Component](https://nextjs.org/docs/pages/api-reference/components/script) in your Next.js app just before the end of the `` tag in your `src/app/layout.js` file: ```javascript title="src/app/layout.js" import Script from 'next/script' // ... ``` | Attribute | Required | Meaning | | ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `team` | no | The team id. Without it, Strife resolves the team from the page's host among the editor's own teams. Pass it to skip the host lookup; together with `document-id` the host need not be registered at all. | | `document-id` | no | The Strife content document id of the page, the one Studio shows in the editor URL. In `Content/ByUrl*` index rows that is usually the `docId` field, not the row's own `id`. Preferred: Strife opens exactly that document, which also covers virtual sub-pages. Without it, Strife resolves the page URL through the content index. | | `api` | no | The Strife API origin. Defaults to `https://api.strife.app`. | | `lang` | no | Language of the toolbar's labels. Defaults to the page's ``: Swedish for `sv`, English for everything else. | The element renders only when the cookie is present, the page is top-level (not framed) and the URL does not carry `?token=`. Collapsed it is a small tab on the right edge with the Strife mark; hovering, focusing or tapping it unfolds two icon actions with tooltips, **edit in Strife** and **hide**. The tooltips use native Interest Invokers (`interestfor` + `popover="hint"`) in Chrome and Edge 142+, and a built-in fallback elsewhere. Style it from outside with `strife-toolbar::part(island)`, `::part(mark)`, `::part(edit)`, `::part(hide)` and `::part(tooltip)`, or move it with a rule on `strife-toolbar` itself (it is `position: fixed`, vertically centred on the right edge by default). ## Cookies and consent `strife-toolbar` is a first-party, host-only cookie holding the value `1`, set by the toolbar script after the editor arrived from Strife. Classify it as a necessary/functional cookie in your consent tool. ## Limitations * The handshake is not signed. Any page that opens your site with `window.open` can make the toolbar appear in that browser; the button only leads to Strife's login, so nothing is exposed. * Safari caps script-set cookies to seven days of Safari use without a visit to the site. An editor who browses the site weekly keeps the connection; otherwise she opens the page from Studio again. * Multi-language sites open in the editor's current locale, not necessarily the locale of the page. ## Troubleshooting * **The toolbar never appears after opening the page from Studio**: the page must be top-level (not framed), the address must not carry `?token=`, and the tab must still know its opener. A site that sends `Cross-Origin-Opener-Policy` (`same-origin` or `same-origin-allow-popups`), or a script that clears `window.opener` before the toolbar module runs, severs the connection; so does closing the Studio tab before the page has loaded. After a play, `document.cookie` should contain `strife-toolbar=1`. * **Clicking lands on the content list instead of the document**: pass `document-id`, or register the host the site is served on for the team. * **`None of your teams is registered for …`**: the editor is not a member of a team that has this host registered. Register the host, or pass `team` together with `document-id`. --- # Snapshots on an Astro site that queries the index Source: https://strife.app/docs/how-to-guides/snapshots-astro-without-the-sdk Serve snapshots from an Astro site that queries the Content/ByUrl index itself, without the SDK's snapshot middleware or a dedicated snapshot route. If your Astro site resolves pages by querying `Content/ByUrl` directly — a middleware that looks the current URL up in the index and puts the row on `Astro.locals` — you do not need the SDK's snapshot middleware, the `snapshot/[token].astro` page, or any new route to serve snapshots. A snapshot's rows carry the snapshot path as their `url`, so the lookup you already have resolves them. **The integration is one clause in one query, plus three projected fields.** This guide is the worked version of the contract in [Snapshots → Serving snapshots without the SDK](https://strife.app/docs/reference/snapshots.md#serving-snapshots-without-the-sdk). Read that section for the rules; read this one for the code. > [!NOTE] > **Vocabulary.** Editors see these as **snapshots** in Strife. The mechanism keeps the name `snapshot` everywhere you touch it — the `/snapshot/{token}` path, `status: "snapshot"`, `snapshotToken`, `snapshotName`. Same thing, two audiences. ## Before you start * **Deploy the index.** Run [`strife push`](https://strife.app/docs/reference/cli/commands.md#strife-push) from a `@strifeapp/strife` release that ships snapshots. Until that has happened, Strife refuses to create a snapshot at all, so nothing can reach your site. * **Render on demand.** Snapshot paths must not be prerendered, statically generated, or cached at the edge. On a site with `output: "server"` this is already true; on a hybrid site, make sure the route that resolves pages is `prerender = false`. * **You do not need `@strifeapp/astro` upgraded.** This path uses no SDK snapshot API. A site pinned to a pre-snapshot version of the package works exactly the same. ## 1. Admit `status == "snapshot"` — in the by-URL lookup only Your visibility predicate today is some form of "published, plus the legacy null-status fallback". Snapshot rows carry `status: "snapshot"` and `draft: true`, so nothing you have matches them. Add the one branch, and add it **only** to the query that resolves the current page by exact URL: ```typescript // src/data/contentIndex.ts export function visibleByUrlQuery( session: IDocumentSession, locale: string, url: string, editMode: boolean, ): IDocumentQuery { if (editMode) { return visibleContentQuery(session, locale, editMode).whereEquals("url", url); } // A snapshot's rows carry the snapshot URL itself ("{root-slug}/snapshot/{token}"), // so admitting status = "snapshot" here is the whole integration. Exact-URL lookups // ONLY — listings stay published-only, or they would enumerate secret snapshot tokens. return session .query({ indexName: CONTENT_INDEX }) .whereEquals("locale", locale) .andAlso() .openSubclause() .whereEquals("status", "published") .orElse() .whereEquals("status", "snapshot") .orElse() .openSubclause() .whereEquals("status", null) .andAlso() .whereEquals("draft", false) .closeSubclause() .closeSubclause() .andAlso() .whereEquals("url", url); } ``` Three things about that query are load-bearing: * **The locale clause.** Snapshot `url`s coincide across languages whenever the site's root slug does not vary by locale, and your code cannot tell which case it is in. Always pair `url` with the resolved locale. A site on this path resolves the **exact** locale only — there is no `snapshotLocale` fallback here, so a reviewer who switches to a language the snapshot never had gets your ordinary not-found. * **The url clause stays outside the visibility subclause.** Keep the OR-branches wrapped so the caller's `url` binds with AND. A stray `orElse` at the top level turns "published *or* snapshot, at this URL" into "published, *or* anything shared anywhere". * **Listings keep the old predicate.** Collection queries, sitemaps, hreflang alternates and search all stay published-only. A listing that admits snapshot rows publishes the secret tokens. ## 2. Project the three fields you will read The snapshot fields are stored in the index, so they come back through `selectFields`. Add them where you project the current page's row: ```typescript // src/middlewares/loadRouteData.ts async function findPageDataByPath(session, locale, pathname, editMode) { return await visibleByUrlQuery(session, locale, pathname, editMode) .selectFields([ "id", "displayName", "url", "collection", "status", // "snapshot" tells the rest of the site what it is looking at "snapshotName", // the editor's label, for an optional banner "expiresAt", // UTC round-trip string, for an optional banner "publishedDate", // …your existing fields ]) .firstOrNull(); } ``` `collection` comes back exactly as it does for the published document, so your view mapping picks the same layout and components it always would. That is the point of this approach: a snapshot is not a special kind of page, it is the same page with unpublished content. ## 3. Let your published-check pass a snapshot row Most sites of this shape have a guard that 404s anything without a publish date. A snapshot deliberately has none: ```typescript // src/middlewares/checkPublished.ts const isPublished = pageData && !pageData.deleted && // A snapshot renders a frozen, unpublished snapshot on purpose; its row only // exists while the snapshot is active (expiry soft-deletes it). (pageData.status === "snapshot" || (pageData.publishedDate && new Date(pageData.publishedDate) < new Date())); ``` **You do not need an expiry check.** Expiry and revocation work by the rows disappearing: Strife soft-deletes the snapshot, and the index drops its rows — normally within about a minute of the instant, and at the next worker start if an alarm was missed. `expiresAt` is on the row if you want to show it, or to add a stricter check of your own. ## 4. Optional: tell the reviewer what they are looking at Nothing above renders a banner, and the page works without one. If you want it, the row carries what you need: ```astro --- // src/layouts/Layout.astro const page = Astro.locals.pageData; --- {page?.status === "snapshot" && ( )} ``` Render `snapshotName` as **text only**, never `set:html`. It is editor-typed input. ## 5. Own the hygiene the SDK would have set This is the part a raw integration inherits, and the part worth reviewing before you ship. On snapshot responses: | What | Why | | --- | --- | | `X-Robots-Tag: noindex, nofollow` | The URL is a secret; keep it out of search indexes. | | `Cache-Control: private, no-store`, and no CDN rule that overrides it | A cached lookup serves a revoked link until the cache expires. | | `Referrer-Policy: no-referrer` | Otherwise the token leaks in the `Referer` of everything the page links to. | | No Open Graph or social tags | A link preview would fetch and cache the page somewhere else. | | No analytics beacon | A snapshot is not audience traffic, and the beacon carries the path — that is the token. | | Your own edit/preview affordances stay off | A valid editor token in the request must not switch on draft branching or a live-preview client on a snapshot path. | The last row is the one that bites. If your site imports a live-preview client unconditionally, the editor's canvas can push draft content into a page that is supposed to be frozen — the reviewer's link and the editor's view then disagree. Gate that import on edit mode, and make sure edit mode is false when `status === "snapshot"`. Also check your locale-redirect layer: if the site 301s prefix-less paths onto a locale prefix, a snapshot URL passes through it like any page. That is fine, as long as the redirect preserves the path and the redirected request still runs the lookup above. ## What you are not building Worth stating, because the SDK path has all of these and this one has none: * No `/snapshot/[token].astro` page and no route registration — the snapshot path *is* a URL your resolver already handles. * No `snapshotToken` query and no token validation — you match on `url`, and an unknown token simply matches nothing. * No expiry logic. * No new dependency or SDK version bump. ## Verify it end to end 1. In Strife, open a page with unpublished changes and create a snapshot. Copy the link. 2. Open it in the language the snapshot was created from → the page renders in your normal design, with the draft's content, plus your banner if you added one. 3. Open the same token under a different locale prefix → your ordinary 404. (Exact locale only, by design.) 4. Load a listing that includes the page → the snapshot is not in it, and the token appears nowhere in the HTML. 5. Revoke the snapshot in Strife, wait a moment, reload → 404. 6. Check the response headers from step 2 against the table above. If step 2 renders the *published* version instead of the draft, your lookup found the canonical row first: the snapshot branch is missing from the query that actually resolved the page, or a second by-URL query downstream re-resolved it with the published-only predicate. --- # Use the docs from AI tools Source: https://strife.app/docs/how-to-guides/use-the-docs-from-ai-tools Search and read the Strife docs from Claude, Cursor, VS Code and other AI tools: the docs MCP server, llms.txt and every page as markdown. The Strife docs, both the developer docs and the user guide, are made to be read by AI assistants as well as by people. Connect the docs MCP server and your assistant searches the docs and reads the pages it needs to answer. Tools without MCP can use llms.txt or the markdown version of any page. ## Connect the docs MCP server The docs are an MCP server at `https://strife.app/docs/mcp`. It needs no account or key, and it has three read-only tools: * `search_docs` searches the developer docs and the user guide, and returns the best matching sections, each with an excerpt and its address. * `get_page` returns a page as markdown, by its path below `/docs` or its full address. * `list_pages` lists every page with a one-line description. **Claude Code** ```sh claude mcp add --transport http strife-docs https://strife.app/docs/mcp ``` Add `--scope user` to have it in every project, not only the current one. Run `/mcp` in Claude Code to check that it is connected. **Claude** In Claude on the web or in the desktop app, open **Settings → Connectors**, choose **Add custom connector** and enter `https://strife.app/docs/mcp` as the URL. **Cursor** Add the server to `~/.cursor/mcp.json` for every project, or to `.cursor/mcp.json` in one project: ```json { "mcpServers": { "strife-docs": { "url": "https://strife.app/docs/mcp" } } } ``` **VS Code** Add the server to `.vscode/mcp.json` in your project, or run **MCP: Add Server** from the Command Palette: ```json { "servers": { "strife-docs": { "type": "http", "url": "https://strife.app/docs/mcp" } } } ``` Other MCP clients connect the same way: a remote server over Streamable HTTP at `https://strife.app/docs/mcp`. Once it is connected, ask about Strife as you would ask a colleague, for example *How do I define a template with defineType?* or *How do editors restore a snapshot?* Mentioning the Strife docs in the question makes the assistant use them instead of answering from memory. ## llms.txt and llms-full.txt [llms.txt](https://strife.app/docs/llms.txt) lists every page with its description and a link to its markdown version, in the [llms.txt format](https://llmstxt.org). [llms-full.txt](https://strife.app/docs/llms-full.txt) holds every page in full in one file, for tools that take a whole document at once. ## Every page as markdown Add `.md` to the address of any page to get it as markdown, for example [strife.app/docs/reference/cli/schemas.md](https://strife.app/docs/reference/cli/schemas.md). The start page is `readme.md`. The blocks of the docs become standard markdown and every link is a full address, so a page works on its own. The **Copy page** button at the top of each page copies the same markdown, ready to paste into a chat. ## Context7 The docs are also on [Context7](https://context7.com), as the library `/llmstxt/strife_app_llms-full_txt`, for assistants that use Context7's MCP server. --- # Strife technical reference Source: https://strife.app/docs/reference/reference-overview This is the reference part of the documentation. Here you will find the technical details of the SDKs, APIs and configuration options. * SDKs * API * Configuration * Data access * ... --- # SDK overview Source: https://strife.app/docs/reference/sdk-overview --- # Templates Source: https://strife.app/docs/reference/templates Templates in Strife serve as the foundation for creating structured and consistent content. These predefined templates establish the fields, and structure, for all content stored in the database. There are two types of templates in Strife; [Document Templates](https://strife.app/docs/reference/templates.md#document-templates) and [Content Templates](https://strife.app/docs/reference/templates.md#content-templates). ### Document Templates The Document Template serves as template for creating documents in the database. It can incorporate various fields types to meet diverse needs. In addition to defining the fields and structure, there are several other significant aspects of the document template worth exploring. #### Collection The document template specifies the collection name, which is utilized to query the database for all content created using that particular template. This collection name is assigned during template creation and is stored within the metadata section of each document in the database. ```json "@metadata": { "@collection": "Posts", ... } ``` > [!NOTE] > If you are using C#, the collection name is stored alongside the Type property to facilitate model binding and serialization. For detailed instructions on setting up model binding in C#, please consult [this provided tutorial](https://strife.app/docs/tutorials/model-binding-in-c.md). > [!NOTE] > The Collection plays a crucial role in utilizing and comprehending RavenDB. For a deeper understanding of RavenDB, please explore [additional resources available here](https://strife.app/docs/explanation/ravendb.md). #### Enable URL When creating the document template, you have the option to enable or disable the indexing of content URLs. When enabled, content created from the template is treated as web pages, and a URL is automatically generated and indexed based on the content's slug and hierarchy. This enables easy web access to the content. When disabled, the content is accessible solely by querying the database or referencing from other content. > [!NOTE] > For additional details on the URL indexing, please [refer to this resource](https://strife.app/docs/reference/database/index-url.md). ### Content Templates The Content Template serves as a reusable preset of fields designed for integration within a Document Template or a Chapters field. It's important to note that a Content Template is not meant for creating documents in the database. Instead, any content generated from a Content Template is always stored within the document that uses that particular Content Template. ### Creating templates Templates can be created either through the graphical interface under Settings in Strife Studio, or by [creating and deploying source-controlled JSON templates](https://strife.app/docs/reference/templates/defining-templates-with-json.md). --- # Defining Templates with JSON Source: https://strife.app/docs/reference/templates/defining-templates-with-json In addition to using the graphical interface in Strife Studio, templates can also be defined using JSON configuration. This allows templates to be stored in source control and automatically synced to Strife as part of your deployment pipeline, depending on your chosen framework and setup. > [!NOTE] > Automatic deployment is included when using the Strife Astro integration `@strifeapp/astro` ### Template Properties | Property | Value | | -------------- | ---------------------------------------------------------------------------------------------- | | displayName | The name of the template displayed in Strife Studio. | | description | A description shown as a hint for editors in Strife Studio. | | collection | The RavenDB collection where documents based on this template will be stored. | | type | Reserved for C# model binding. | | editors | An array defining the fields in the template. See below for details. | | normalizedName | A normalized internal name used for reference in Strife Studio. | | templateType | Defines the template type: `dt` (Document Template) or `ct` (Component Template). | | composable | Boolean indicating if content based on this template can be composed inside other documents. | | filterable | Boolean indicating if this template should be available as a filter option in Strife Studio. | | disable URL | Boolean controlling whether content created from this template should have a public URL. | | archived | Boolean indicating if the template is archived. | | icon | The icon name used for display in Strife Studio. See [Icons](https://strife.app/docs/reference/icons.md) for available names. | | allowedOrigins | Optional. Normalized names of the templates whose documents may be this template's origin; absent or a non-empty list, never `[]`. Strife Studio's compose dialog and Set origin then offer only those documents; the API does not validate origins against it. Written by `defineType`'s `from`. | | allowedOriginIds | Optional. Ids of specific documents that may be this template's origin, beside or instead of `allowedOrigins`; absent or a non-empty list, never `[]`. Same Studio-side behaviour, same absence of server-side validation. Written by `defineType`'s `from: { id }`, where the id is read from an environment variable because it differs per workspace. | | baseProperties | `{ "displayName": { "localizable": true/false }, "slug": { "localizable": true/false } }` — whether the document's name and slug have one value per locale (`true`) or one shared value (`false`). Written by `defineType`'s `baseProperties`, which sends only the flags the type states (`{}` when none). An unstated or absent flag is the default: `slug` localizable when the team has two or more locales, `displayName` not. A template saved without `baseProperties` keeps the flags it already has; one saved with it stores exactly what it states, and a flag it leaves out goes back to the default. Readers always get strings, resolved to the requested locale. | | @metadata | RavenDB metadata and model binding information. | > [!NOTE] > **Note:** The `@metadata` property is required for the template to be accepted by Strife and made available inside Strife Studio. ### Field properties | Property | Value | | ----------- | ---------------------------------------------------------------------------------------------------------------------- | | label | The label shown to editors when editing the field. | | description | Optional tooltip text for the field. | | editor | The editor type configuration. See example below and check out [the fields reference](https://strife.app/docs/reference/fields.md) for available types. | | localizable | Boolean indicating if the field should be localizable (available only when localization is enabled). | ### Editor properties | Property | Value | | ------------ | ----------------------------------------------------------------------------------------- | | name | The editor component name. | | type | The editor type. | | propertyName | The property name used in the RavenDB document. | | attributes | Field-specific configuration. See each editor's documentation for supported attributes. | | options | Additional options for the editor. See each editor's documentation for supported options. | > [!NOTE] > You can find specific editor configurations and available options on the respective [Field pages](https://strife.app/docs/reference/fields.md). ### Example ```json { "displayName": "Page", "description": null, "collection": "Pages", "type": null, "editors": [ { "label": "Sections", "description": "", "editor": { "name": "str-chapters", "type": "chapters", "propertyName": "sections", "attributes": { "hint": "

Page sections

" }, "options": { "availableTypes": [ "text", "content", "hero", "bento" ] } }, } ], "templateType": "dt", "normalizedName": "page", "disableURL": false, "archived": false, "icon": "home", "hint": "A demo page", "searchFields": [], "filterFields": [], "composable": true, "filterable": true, "@metadata": { "@collection": "Templates", "Raven-Clr-Type": "Wieldy.Core.Models.Template, Wieldy.Core" } } ``` --- # Fields Source: https://strife.app/docs/reference/fields Fields define the structure and content of your templates. Each field specifies the shape and characteristics of the data that will be stored in the database. > [!WARNING] > This documentation page is still in progress and may not be fully complete. Please check back later for updates. ### Basic Field Settings All fields come with a standard set of basic settings:
OptionDescription
Name*This setting is mandatory. It determines the property name used for storing and retrieving data from the database. It should be a unique identifier for each field and in camel case.
Label*This is the text used as a field label when you're editing the field inside Strife. It provides a human-readable name for the field.
Tooltip
This setting allows you to provide additional information or hints about the field. Tooltips are displayed when users hover over or focus on the field.
AutofocusAutofocus can be enabled to make the field automatically selected or focused when editing, streamlining the user experience.
Validation textYou can define custom validation text here to provide guidance or error messages when users input data that doesn't meet specific criteria.
Tab GroupGroups fields under a specific tab in the editor
LocalizableEnabling this settings allows the field to be localizable
Tab groupWhen your template includes a Tab Group, use this setting to determine which tab the field should appear under in the editor. See this page for more info.
Each field, depending on its type, may offer additional settings to further customize its behavior. For specifics on these additional settings, please refer to the documentation for each respective field. ### JSON Definition When templates are defined using JSON, the basic field settings form the foundation of each field's configuration within the `editors` array. These settings control how fields behave and appear inside Strife Studio. For additional information on defining templates with JSON, [refer to this page](https://strife.app/docs/reference/templates/defining-templates-with-json.md). Each field in the `editors` array follows this structure: ```json { "label": "...", // Label "description": "...", // Tooltip "editor": { "name": "...", // Field component name* "type": "...", // Field component type* "propertyName": "...", // Name "attributes": { "autofocus": true, // Autofocus "validationText": "...", // Validation text "tabGroup": "...", // Tab Group ... } }, "localizable": true // Localizable } ``` > [!NOTE] > \*Refer to each field’s documentation for component name, type and additional attributes. ### Live Preview Integration for Fields Fields will automatically transmit their current state to the live preview while a user is editing a field. To enable live preview integration, the website's markup must be upgraded to incorporate Strife view components. You can find detailed instructions on how to set up the live preview [here](https://strife.app/docs/reference/live-preview.md). Please refer to the documentation for each respective field to learn about the view components compatible with that specific field. --- # Text Source: https://strife.app/docs/reference/fields/text The Text field type is one of the most commonly used fields. It saves a string to the database and provides the Edit view with a simple text input.

Strife Studio screenshot of a Text field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
PlaceholderA brief hint or instruction displayed in an input field to guide users on the expected content or format.
SpellcheckEnables or disables automatic spell checking in the browser
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-input` * **Type:** `text` * Reference ID: `str-input|text` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-input", "type": "text", "propertyName": "...", ... "attributes": { "spellcheck": true, "placeholder": "..." } }, ... } ``` ### Live preview The compatible Strife Web Components for a Text field are any of the text or container components. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Paragraph Source: https://strife.app/docs/reference/fields/paragraph The Paragraph field, similar to the Text field, stores a string in the database, but it is specifically designed to facilitate the editing of longer text.

Strife Studio screenshot of a Paragraph field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
PlaceholderA brief hint or instruction displayed in an input field to guide users on the expected content or format.
SpellcheckEnables or disables automatic spell checking in the browser
DisplayOption between plain text and indented JSON format for text presentation. Default is text.
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-textarea` * **Type:** `text` * Reference ID: `str-textarea|text` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-textarea", "type": "text", "propertyName": "...", ... "attributes": { "spellcheck": true, "placeholder": "...", "display": "..." // text | json } }, ... } ``` ### Live preview The compatible Strife Web Components for a Paragraph field are any of the text or container components. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Rich Content Source: https://strife.app/docs/reference/fields/rich-content The Rich Content field empowers editors to create dynamic and visually appealing content, which is then stored in the database as HTML.

Strife Studio screenshot of a Rich Content field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
Menu buttonsSelects which buttons appear in the slash-menu and which heading levels (H1–H6) are enabled. See Menu button values
Placeholder Document~Specifies a node scheme that the document must follow.
Lock Placeholder Document~Specifies whether the user should be prevented to add more nodes after what's specified under the placeholder-document.
> [!WARNING] > A tilde (**\~**) denotes that a setting is available in developer preview only. #### Menu button values Pass `menuButtons` as an array of strings. Heading values (`heading1` through `heading6`) control which heading levels the editor accepts. Other values enable the corresponding slash-menu items.
ValueDescription
heading1…heading6Enable the corresponding heading level. Include only the levels you want available.
bulletListUnordered list slash-menu entry.
orderedListNumbered list slash-menu entry.
checkListTask list with checkboxes.
imageImage insert slash-menu entry.
videoVideo insert slash-menu entry.
tableTable insert slash-menu entry.
> [!NOTE] > Inline formatting (bold, italic, underline, strikethrough, link, blockquote, details) is always available from the text-selection menu, independent of `menuButtons`. ### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-textarea` * **Type:** `html` * Reference ID: `str-textarea|html` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-textarea", "type": "html", "propertyName": "...", "attributes": { "menuButtons": ["heading1", "heading2", "bulletList"], "placeholderDocument": "{\"content\":\"heading paragraph+\",\"placeholders\":{\"heading\":\"Enter title\",\"paragraph\":\"Start writing…\"}}" } }, ... } ``` #### Placeholder Document > [!WARNING] > Developer preview. API may change. `placeholderDocument` takes a JSON string with two optional keys: * **`content`** — a ProseMirror content expression that constrains which node types the document contains and in what order. Examples: `"heading"` (exactly one heading), `"heading paragraph+"` (one heading followed by one or more paragraphs), `"heading paragraph*"` (heading with optional paragraphs). * **`placeholders`** — an object mapping ProseMirror node-type names to placeholder text shown when the node is empty. Example configuration: ```js // Rendered as a JSON string in the template attribute: { "content": "heading paragraph+", "placeholders": { "heading": "Enter title", "paragraph": "Start writing…" } } ``` **Valid node-type names** for `placeholders` (and `content`): * `heading` — all levels use the same node type; the `level` attribute (1–6) is set by the editor. Use `heading`, not `heading1`. * `paragraph` * `bulletList`, `orderedList`, `listItem` * `blockquote` * `codeBlock` * `image`, `video` **To produce the final attribute value**, JSON-stringify your config object — the JSON must be embedded as a string in the `placeholderDocument` attribute. When building templates in code: ```js attributes: { placeholderDocument: JSON.stringify({ content: "heading paragraph+", placeholders: { heading: "Enter title", paragraph: "Start writing…" } }) } ``` ### Live preview The compatible Strife Web Components for a Rich Content field are container components only. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Number Source: https://strife.app/docs/reference/fields/number The Number field is designed for storing, validating, and formatting numeric data, with support for various numerical validation features.

Strife Studio screenshot of a Number field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
PlaceholderA brief hint or instruction displayed in an input field to guide users on the expected content or format.
MinDefines the minimum permissible numeric value, establishing a lower limit for data entry.
MaxEstablishes the maximum allowed numeric value, setting an upper limit for data entry.
StepSpecifies the extent of value change when users interact with the field. Set the desired increment, such as 1 for whole numbers, 0.1 for one decimal place, 0.01 for two decimal places, and so on.
> [!WARNING] > Please note that the Step setting is a mandatory requirement for enabling the use of decimal numbers within Strife Studio. ### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-input` * **Type:** `number` * Reference ID: `str-input|number` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-input", "type": "number", "propertyName": "...", ... "attributes": { "placeholder": "...", "min": 0, //Any number "max": 100, //Any number "step": "..." } }, ... } ``` ### Live preview The compatible Strife Web Components for a Number field are any of the text or container components. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Date Source: https://strife.app/docs/reference/fields/date The Date field allows users to input a date via a date picker. The selected date is stored as a string value in the database.

Strife Studio screenshot of a Date field

### Settings The Date field does not feature any distinctive settings beyond the standard ones. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md). ### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-input` * **Type:** `date` * Reference ID: `str-input|date` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-input", "type": "date", "propertyName": "...", ... }, ... } ``` ### Live preview `str-time` is the preferred Strife Web Component for a Date field, although any of the text or container components can also be used. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Date Time Source: https://strife.app/docs/reference/fields/date-time The Date Time field allows users to input a date including time via a date picker. The selected date is stored as a string value in the database.

Strife Studio screenshot of a Date Time field

### Settings The Date field does not feature any distinctive settings beyond the standard ones. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md). ### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-input` * **Type:** `datetime-local` * Reference ID: `str-input|datetime-local` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-input", "type": "datetime-local", "propertyName": "...", ... }, ... } ``` ### Live preview `str-time` is the preferred Strife Web Component for a Date Time field, although any of the text or container components can also be used. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Image Source: https://strife.app/docs/reference/fields/image The Image field lets you to crop, zoom, and insert images effortlessly. It stores the optimized image URL along with crop data in the database.

Strife Studio screenshot of an Image field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
WidthSpecifies the desired width of the displayed image.
HeightSpecifies the desired height of the displayed image. Set to 0 for a width-only image that keeps the source aspect ratio — the height is derived from the original, and crop/zoom are disabled. In defineType the same thing is spelled height: 'auto'.
FormatSpecifies the image format in which the image will be stored. Default is webp
Padding colorHex color used for the padded area of the image when the crop area is smaller than the source.
Padding alphaAlpha value between 0 and 1 for the padded area's transparency.
Hide alt textWhen enabled, the alt text field is hidden in the image editor.
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-image` * **Type:** `image` * Reference ID: `str-image` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-image", "type": "image", "propertyName": "...", ... "attributes": { "width": 300, "height": 200, //0 = width-only, keeps the source aspect ratio "format": "...", //webp,png,jpeg,etc "paddingColor": "...", //Hex color format "paddingAlpha": 0.5, "hideAlt": false } }, ... } ``` > [!NOTE] > In the JSON template, `height` is always a number — `0` is the width-only convention. The `'auto'` spelling exists only in [`defineType`](https://strife.app/docs/reference/cli/schemas.md), which compiles it to `0` for you. ### Live preview The compatible Strife Web Component for an Image field is the `str-image` component. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Image Group Source: https://strife.app/docs/reference/fields/image-group The Image field lets you define a set of images for different media/resolutions to crop, zoom, and insert images effortlessly. It stores the optimized image URLs along with crop data in the database.

Strife Studio screenshot of an Image Group field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
MediasSpecifies the various media formats by providing the format name/key, width, and height to add images tailored to different media requirements. Examples of medias could be 'Desktop', 'Tablet' and 'Mobile'.
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-image-group` * **Type:** `image-group` * Reference ID: `str-image-group` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-image-group", "type": "image-group", "propertyName": "...", ... "attributes": { "paddingColor": "..." //Hex color format "paddingAlpha": 0.5, //Number between 0-1 "hideAlt": false }, "options": { "medias": [ { "name": "...", "width": 300, "height": 200 }, ... ] } }, ... } ``` ### Live preview The compatible Strife Web Component for an Image Group field is the `str-picture` component. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Toggle Source: https://strife.app/docs/reference/fields/toggle The Toggle field saves a binary value of either 'true' or 'false' in the database.

Strife Studio screenshot of a Toggle field

### Settings The Toggle field does not feature any distinctive settings beyond the standard ones. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md). ### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-switch` * **Type:** `toggle` * Reference ID: `str-switch|toggle` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-switch", "type": "toggle", "propertyName": "...", ... }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Slug~ Source: https://strife.app/docs/reference/fields/slug > [!WARNING] > The tilde (**\~**) denotes that the field is available in developer preview only. ### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
PlaceholderPlaceholder to display when no value is entered
Auto CheckThe option to call an endpoint for validating the input as the user types
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-input` * **Type:** `slug` * Reference ID: `str-input|slug` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-input", "type": "slug", "propertyName": "...", "options": { "autoCheck": { "csrf": "...", "src": "..." } } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Related Source: https://strife.app/docs/reference/fields/related Create a document relation ### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
Multi selectAllow multiple values to be selected
Restrict collectionsRestrict the collections that can be related
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-related` * **Type:** `related` * Reference ID: `str-related` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-related", "type": "related", "propertyName": "...", "attributes": { "multiSelect": true, }, "options": { "allowedCollections": [...] //Collection names } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Assets Source: https://strife.app/docs/reference/fields/assets Create a lists of assets ### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
Restrict typesRestrict the types of assets that can be added to this assets list
SizeThe maximum number of assets that can be added to this assets list
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-assets` * **Type:** `assets` * Reference ID: `str-assets` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-assets", "type": "assets", "propertyName": "...", "attributes": { "size": 3, }, "options": { "availableTypes": [...] //1(image)|2(video)|3(file) } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Checkbox Source: https://strife.app/docs/reference/fields/checkbox The Checkbox field saves a binary value of either 'true' or 'false' in the database.

Strife Studio screenshot of a Checkbox field

### Settings The Checkbox field does not feature any distinctive settings beyond the standard ones. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md). ### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-switch` * **Type:** `checkbox` * Reference ID: `str-switch|checkbox` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-switch", "type": "checkbox", "propertyName": "...", ... }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Link Source: https://strife.app/docs/reference/fields/link The Link field enables users to insert links, storing an object in the database containing link text, URL, and target options.

Strife Studio screenshot of a Link field

### Settings The Link field does not feature any distinctive settings beyond the standard ones. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md). ### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-link` * **Type:** `link` * Reference ID: `str-link` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-link", "type": "link", "propertyName": "...", ... }, ... } ``` ### Live preview The compatible Strife Web Component for a Link field is the `str-anchor` component. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Chapters Source: https://strife.app/docs/reference/fields/chapters The Chapters field allows dynamic content creation using predefined templates, storing the content as an array of objects in the database.

Strife Studio screenshot of a Chapters field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
Restrict typesSets the content templates available for use within the Chapters field
SizeOptional setting for limiting the number of chapters allowed in the chapters editor
HintA short description displayed inside the chapters editor to guide authors.
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-chapters` * **Type:** `chapters` * Reference ID: `str-chapters` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-chapters", "type": "chapters", "propertyName": "...", "attributes": { "hint": "...", "size": 3 //Any number }, "options": { "availableTypes": [...] //Array of normalized names of content templates } ... }, ... } ``` ### Live preview The compatible Strife Web Component for a Chapters field is any of the container components. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). > [!NOTE] > For a comprehensive front-end implementation example of the Chapters field, please [consult the provided how-to guide](https://strife.app/docs/tutorials/create-a-dynamic-employee-list-using-the-chapters-field.md). --- # References Source: https://strife.app/docs/reference/fields/references The References editor lets you connect existing documents from other collections directly into your content, enabling structured reuse instead of duplication. Functionally similar to adding Chapters, the References editor differs in that it does not create inline content bound to the current document. Instead, it allows you to **reference one or more existing documents** from a specified collection. This makes it easy to compose content from shared building blocks while keeping a single source of truth. If needed, editors can also **create a new document in the target collection on the fly** and immediately reference it—without leaving the current editing context. All referenced documents remain fully editable and can be opened and updated directly from where they are referenced, ensuring a smooth and efficient workflow. This approach supports modular content architectures, reduces duplication, and keeps related content consistently up to date across the system. ### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
Restrict typesRestrict the collections that can be added to this reference editor
SizeOptional setting for limiting the number of references allowed
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-references` * **Type:** `references` * Reference ID: `str-references` The settings above map into the `editor` object inside the JSON definition. ```json { ... "editor": { "name": "str-references", "type": "references", "propertyName": "...", "attributes": { "hint": "...", "size": 3 //Any number }, "options": { "availableTypes": [...] //Array of the collection's normalized template name } ... }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Repeatable Source: https://strife.app/docs/reference/fields/repeatable The Repeatable editor allows editors to add multiple values using the same input type, making it ideal for structured lists and repeatable data patterns. A Repeatable editor is configured with **one specific editor type**, which is then reused for every item in the list. Supported editor types include standard inputs (text, number, date), textarea, links, and combo boxes. Mixing different editor types within the same Repeatable editor is not supported by design—this ensures consistent data output and predictable rendering. From a data perspective, the Repeatable editor outputs an **array of value objects**, where each item follows the schema of the selected editor type. This makes the field straightforward to consume in templates, APIs, and custom components. The Repeatable editor is well suited for use cases such as tag lists, external links, key facts, dates, or any scenario where a controlled set of repeated values is required without introducing additional document structure. ### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
Editor TypeSelect the type of editor that can be added to the repeatable. Supported editor types include standard inputs (text, number, date), textarea, links, and combo boxes.
SizeOptional setting for limiting the number of references allowed
Options*Options to display. Only available for combo box editors
External source*Use an external source to fetch options. Only available for combo box editors
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-repeatable` * **Type:** `repeatable` * Reference ID: `str-repeatable` The settings above map into the `editor` object inside the JSON definition. > [!NOTE] > **Note for JSON configuration**\ > When configuring a Repeatable editor using JSON, the editor type is defined by a specific editor ID. Set options.availableTypes to an array containing **exactly one string** with this ID. The correct ID for each editor type is listed on its respective documentation page. ```json { ... "editor": { "name": "str-repeatable", "type": "repeatable", "propertyName": "...", "attributes": { "hint": "...", "size": 3, //Any number "externalDataSource": "..." //*Combo Box editors only }, "options": { "availableTypes": [...], // Array with single item allowed with editor ID for repeatable editor "items": [ //*Combo Box editors only { "name": "...", "value": "...", "color": "...", //Optional, hex color format "icon": "...", //Optional, name of icon "avatar": "..." //Optional, url to avatar }, ... ], } ... }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Collection Source: https://strife.app/docs/reference/fields/collection The Collection field allows the user to query and list content using a filter, storing the filter and query as an object in the database.

Strife Studio screenshot of a Collection field

> [!CAUTION] > OBSOLETE – This field is no longer supported ### Settings The Collection field does not feature any distinctive settings beyond the standard ones. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md). ### Live preview The compatible Strife Web Component for a Chapters field is any of the container components. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). > [!NOTE] > For a comprehensive front-end implementation example of the Collection field, please [consult the provided how-to guide](https://strife.app/docs/reference/fields/collection.md). --- # Content Template Source: https://strife.app/docs/reference/fields/content-template The Content Template field instantiates editing of a content template. Stores as an object in the database, including the fields from the chosen content template.

Strife Studio screenshot of a Content Template field

> [!NOTE] > For further information on templates, please refer to this [reference guide](https://strife.app/docs/reference/templates.md). ### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
Content Template*Selects the content template to use for editing
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-content-template` * **Type:** `content-template` * Reference ID: `str-content-template` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-content-template", "type": "content-template", "propertyName": "...", "attributes": { "templateId": "..." //The ID of the content template } }, ... } ``` ### Live preview To enable live preview for the Content Template field, refer to each field within the content template to find compatible Strife Web Components, ensuring seamless integration. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Combo Box Source: https://strife.app/docs/reference/fields/combo-box The Combo Box field lets you choose one or multiple values from a preset selection in a searchable drop-down. It stores these selections as an array of values in the database.

Strife Studio screenshot of an Combo Box field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
PlaceholderDisplay a placeholder text in the search field after opening the combo box
IconDisplays an icon before the selected value in the combo box
Multi selectEnables multi-select, allowing users to choose multiple options
OptionsDefines the choices presented in the drop-down. Each option is represented as an object containing a name, value, color hex value (optional), icon name (optional), and avatar url (optional)
Default ValueDefault value to display when no value is selected
External sourceUse an external source to fetch options. Use ${propertyName} to access the value of a property in the URL
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-combo-box` * **Type:** `combo-box` * Reference ID: `str-combo-box` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-combo-box", "type": "combo-box", "propertyName": "...", "attributes": { "placeholder": "...", "defaultValue": "...", "icon": "...", "multiSelect": true, "externalDataSource": "..." }, "options": { "items": [ { "name": "...", "value": "...", "color": "...", //Optional, hex color format "icon": "...", //Optional, name of icon "avatar": "..." //Optional, url to avatar }, ... ] } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Multi Select Source: https://strife.app/docs/reference/fields/multi-select The Multi Select field allows, just like the Combo Box, users to add one or more values of a predefined list, storing them as an array in the database.

Strife Studio screenshot of an Multi Select field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
PlaceholderDisplay a placeholder text in the search field after opening the combo box
Check marksEnables check marks on the selected values
OptionsDefines the choices presented in the drop-down. Each option is represented as an object containing a name, value, and color hex value (optional)
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-multi-select` * **Type:** `multi-select` * Reference ID: `str-multi-select` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-multi-select", "type": "multi-select", "propertyName": "...", "attributes": { "placeholder": "...", "switches": true, //Check marks "externalDataSource": "..." }, "options": { "options": [ { "name": "...", "value": "...", "color": "...", //Optional, hex color format "icon": "...", //Optional, name of icon "avatar": "..." //Optional, url to avatar }, ... ] } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Multi Input Source: https://strife.app/docs/reference/fields/multi-input The Multi Input field allows users to arbitrarily add one or more values of a predefined type, storing them as an array in the database

Strife Studio screenshot of an Multi Input field

### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
TypeSpecifies the type of value to insert, which can be one of the following: Text, Number, Email, URL, Tel, Date Time, Date, Month, or Time
Auto sortDetermines whether the field should automatically sort the inserted values as they are added
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-multi-input` * **Type:** `multi-input` * Reference ID: `str-multi-input` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-multi-input", "type": "multi-input", "propertyName": "...", "attributes": { "inputType": "...", //text|number|email|url|tel|datetime-local|date|month|time "sort": false, } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Table Input~ Source: https://strife.app/docs/reference/fields/table-input The Table Input field enables users to input data in a tabular format, storing it as an array of objects in the database.

Strife Studio screenshot of an Table Input field

> [!WARNING] > The tilde (**\~**) denotes that the field is available in developer preview only. ### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
HeadersA JSON array of strings specifying the column headers. E.g ["Name","Latin","Habitat","Feature"]
Input typesSpecifies the input types for each header using a JSON array of strings. Supported types include 'text', 'number', 'date', 'datetime-local', 'email', 'month', 'tel', 'time', 'url', 'boolean', and 'multistring'. E.g. ["text","text","text","text"]
OptionsA JSON object containing the options for every 'multistring' input type. Use camel case header as property name. E.g. {"columnHeader": []}
SortableEnables sorting in the Table Input field, which allows users to click on column headers for sorting.
Sort bySpecifies the default sorting column header.
Sort directionSpecifies the default sorting direction.
SearchableEnables search for large data sets.
Display row numbersIf enabled, row numbers will be displayed in the Table Input field.
ExportableIf enabled, the table can be exporterd/imported to/from CSV
Export delimiterChoose a delimiter for the export; file formats (CSV, TSV, TXT)
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-table-input` * **Type:** `table-input` * Reference ID: `str-table-input` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-table-input", "type": "table-input", "propertyName": "...", "attributes": { "sortable": true, "sortBy": "...", "sortDirection": "asc", "searchable": false, "rowNumbers": false, "exportable": false, "exportDelimiter": "..." //','|'\t'|';'|'|' }, "options": { "headers": "...", "inputTypes": "...", "options": "...", } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Rich Content (JSON)~ Source: https://strife.app/docs/reference/fields/rich-content-json The Rich Content field empowers editors to create dynamic and visually appealing content, which is then stored in the database as JSON. > [!NOTE] > This field is identical to the [Rich Content field](https://strife.app/docs/reference/fields/rich-content.md), with the only distinction being that it stores its value as JSON in the database. > [!WARNING] > The tilde (**\~**) denotes that the field is available in developer preview only. ### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-textarea` * **Type:** `json` * Reference ID: `str-textarea|json` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-textarea", "type": "json", "propertyName": "...", ... "attributes": { "menuButtons": [...] //heading1|heading2|bold|etc... "placeholderDocument": "..."//heading|paragraph|etc... } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # File~ Source: https://strife.app/docs/reference/fields/file

Strife Studio screenshot of a File field

> [!WARNING] > The tilde (**\~**) denotes that the field is available in developer preview only. ### Settings In addition to the basic settings, this section provides information about unique settings and configurations specific to this field. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
Restrict typesRestrict the allowed types to upload in the File field
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-file` * **Type:** `file` * Reference ID: `str-file` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-file", "type": "file", "propertyName": "...", ... "attributes": { "allowedTypes": "..." } }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Tab Group Source: https://strife.app/docs/reference/fields/tab-group Tab Groups provide a clean and organized way to group fields within the editor interface. They are purely a **visual grouping mechanism** and do **not** affect your content model structure — meaning they do not introduce nested properties in your JSON data. ### Settings The **Tab Group** field includes one specific configuration option **in addition to the basic settings**. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
TabsDefines the collection of tabs within the group. Each tab entry contains a name (displayed in the editor UI) and a value (used internally to map fields to a specific tab).
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-tab-group` * **Type:** `str-tab-group` * Reference ID: `str-tab-group` The settings above map into the `editor.options` object inside the JSON definition. ```json { ... "editor": { "name": "str-tab-group", "type": "str-tab-group", "propertyName": "...", "options": { "tabs": [ { "name": "...", //The name displayed to the editor "value": "..." //Value used as id }, ... ] } }, ... } ``` In this example, two tabs are defined — **Properties** and **SEO** — which organize fields into separate visual sections within the editor. #### How to add a field to a tab group To place a field inside a specific tab within a Tab Group, reference the tab using the format `{propertyName}-{value}`, where: * `{propertyName}` is the Tab Group's `propertyName` field * `{value}` is the specific tab's `value` property **Example:** If your Tab Group has `propertyName: "tabs"` and a tab with `value: "properties"`, the reference would be `"tabs-properties"`. If your Tab Group has `propertyName: "tabGroup"` and a tab with `value: "content"`, the reference would be `"tabGroup-content"`. > [!NOTE] > Note: The prefix must exactly match the `propertyName` defined in the Tab Group's configuration. This link is made using the `tabGroup` attribute inside the field’s `editor.attributes` object. ```json { ... "editor": { ... "attributes": { "tabGroup": [ "tabs-properties" ] } }, ... }, ``` In this example, this field will appear under the **Properties** tab of the defined Tab Group. > **Note:**\ > The prefix `tabs-` must match the `value` defined in the Tab Group’s configuration.\ > For instance, if a tab has `"value": "seo"`, the corresponding field should use `"tabs-seo"`. ### Live preview > [!NOTE] > Tab Groups are **UI-only elements** and have **no effect on Live Preview output**. --- # Radio Group Source: https://strife.app/docs/reference/fields/radio-group The Radio Group editor presents a predefined set of options where only one value can be selected at a time. Each option is defined by a `name` (label shown to the editor) and a `value` (the stored value used in templates and APIs). The editor is displayed in a **tab-style layout**, making it especially well suited for mutually exclusive choices that affect behavior or presentation. Common use cases include toggling appearance settings, selecting alignments, choosing layout variations, or controlling feature states. From a data perspective, the Radio Group editor outputs the `value` of the selected option, ensuring a simple and predictable data structure for rendering logic and conditional handling. The Radio Group editor is ideal whenever a clear, single-choice decision is required and the available options should be immediately visible and easy to compare. ### Settings The **Radio Group** field includes one specific configuration option **in addition to the basic settings**. > [!NOTE] > You can find a comprehensive list of all basic settings in the ['Overview' section](https://strife.app/docs/reference/fields.md).
OptionDescription
OptionsOptions to display in the radio group. Each option must have a name and value while color, icon and avatar are optional
Default valueDefault value to be selected in the radio group
### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-radio-group` * **Type:** `str-radio-group` * Reference ID: `str-radio-group` The settings above map into the object inside the JSON definition. ```json { ... "editor": { "name": "str-radio-group", "type": "str-radio-group", "propertyName": "...", "options": { "items": [ { "name": "...", //The name displayed to the editor "value": "...", //Value stored "icon": "..." //Optional icon name }, ... ] }, "defaultValue": "..." //A value matching an item's value in the items array }, ... } ``` ### Live preview > [!NOTE] > This field does not have any default Strife Web Components. Custom live preview implementations are fully supported. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Slider Source: https://strife.app/docs/reference/fields/slider The Slider field lets users select a numeric value within a range by dragging a thumb. It stores a single number in the database. #### Settings The Slider field does not feature any distinctive settings beyond the standard ones in Strife Studio. Range configuration (`min`, `max`, `step`) is set in the JSON template definition — see below. > [!NOTE] > You can find a comprehensive list of all basic settings in the 'Overview' section. #### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-slider` * **Type:** `slider` * Reference ID: `str-slider|slider` The settings above map into the `editor.attributes` object inside the JSON definition. ```json { ... "editor": { "name": "str-slider", "type": "slider", "propertyName": "...", ... "attributes": { "min": 0, //Lower bound of the range. Default 0. "max": 100, //Upper bound of the range. Default 100. "step": 1, //Increment step when dragging. Default 1. "readonly": false, //Disables interaction when true. Default false. "tooltip": true //Shows percentage tooltip on hover. Default true. } }, ... } ``` The field stores a single number between `min` and `max` in the database. #### Live preview The compatible Strife Web Components for a Slider field are any of the text or container components. > [!NOTE] > For more information on live preview and Strife Web Components, please refer to the [Live preview documentation](https://strife.app/docs/reference/live-preview.md). --- # Video Source: https://strife.app/docs/reference/fields/video The Video field lets editors embed a video in a document from a media asset, a direct URL. It stores the source, playback options, and an optional poster image as an object in the database. #### Settings The Video field does not feature any distinctive template-level settings beyond the standard ones. When editing a document, the field's built-in editor offers a source selector (Media or URL), quality toggle, poster image editor, and playback controls (autoplay, loop, mute, controls, start time). > [!NOTE] > You can find a comprehensive list of all basic settings in the 'Overview' section. #### Define with JSON When defining templates using JSON, this field is represented using: * **Component Name:** `str-video` * **Type:** `video` * Reference ID: `str-video|video` ```json { ... "editor": { "name": "str-video", "type": "video", "propertyName": "..." }, ... } ``` The value stored in the database is an object describing the selected video: ```json { "source": "media", //"media" | "url" "url": "...", //Video URL "quality": "high", //"medium" (720p) or "high" (1080p) for Media source "poster": { //Optional poster image "src": "...", "alt": "", "width": 1366, "height": 768 }, "startTime": "0", //Start offset in seconds "playing": false, //Autoplay "muted": false, "controls": true, "loop": false } ``` #### Live preview This field does not have a default Strife Web Component. To render a video in live preview, read `url`, `poster`, and the playback flags from the stored value and render a native `