Skip to content

Start a client site from the starter kit

The starter kit is a head start. Instead of modelling a site from an empty organization, you install a working set of Contracts, Templates, categories and a demo experience in one step, point a React site at it, and have a real page on screen in under half an hour. Then you change it into your client’s site.

It becomes yours the moment it is installed. Nothing links an installed item back to the kit, a newer kit never changes what you have, and installing again only adds what is missing. You edit, rename or delete any of it freely. The kit is there to get you started quickly, and to be outgrown.

The guide has two halves: setting up the content in ebitex, which takes a few minutes and no code, and running a site against it.

Installed in your organization What it is
An experience Contract and a Landing Contract The base of a page: search and sharing fields, a hero and a list of sections. Extend it for each kind of page you build.
Ten content Contracts Hero, rich text, media, card, feature, banner, call to action, tabs, accordion and grid. They hold only the words and media.
Tab and Accordion item Contracts One tab or one drawer: a label and the sections inside it.
An action Contract A button or a link, used inside hero, card, banner and call to action.
A Template for each, with its own settings The Template says how a Contract is drawn, and its settings hold every choice that belongs to a place: width, background, appearance, a card’s emphasis, a banner’s tone, a grid’s columns, how an accordion behaves.
Eleven category groups Theme, appearance, layout, width, background, aspect ratio, emphasis, tone, action style, accordion behaviour and initially open, each with starter values you can rename and extend.
A Group A heading and an optional eyebrow over any number of sections, with its own spacing and alignment.
Site chrome (header and footer) Two presentations held by one Component, ebitex-site-chrome: the logo, the site name, links and a button, and a footer. Your site fetches it by that id.
A demo experience (optional) A finished home page built only from the kit, named ebitex demo, with a demo Site chrome.

A Contract never stores how it looks. An experience’s hero and sections are presentations: a Template, that Template’s settings, and a Component. Width, background, appearance, tone and emphasis are chosen in the settings, where a section is placed, so one Component can appear in many places in different ways. They are categories, so you can edit the choices in Content without touching code. Tabs and Accordion hold their own items (a label and the sections inside it), so a whole FAQ is one Component you can reuse on every page that needs it.

  • An ebitex account and an organization. Set up your organization covers signing up and where each key is created.
  • Permission to manage Contracts, Templates and the organization’s categories. The install page lists what it needs and tells you which of those you lack before you start. An organization’s owner has all of them.
  • Assets. The kit’s media fields choose images and video from your Assets library, so Assets has to be connected to Content first. The install page does this for you, in one step.
  • Node 20 or newer for the site.
  1. In Content, open Tools → Starter kits. A new organization’s empty Components list also offers Start from a starter kit, which goes to the same page.
  2. Connect Assets if the page asks. Press Connect Assets. It turns on the Assets plugin, creates a channel and a key for Content, and registers them, in one confirmed step. The key is stored inside the registration and is never shown, because nothing needs it again. Private assets stay hidden from Content until you change the channel in Assets.
  3. Read the preview. It lists what installing will add, by kind (about a hundred items with the demo), and how many items you already have, which are kept exactly as they are. It also says which environment the kit will be added to.
  4. Choose whether to include the demo experience. Leave it on to learn from a finished page. Clear it to add only the building blocks.
  5. Select Install the kit. It runs as a background job, and the page tells you when it is done. If it stops, nothing you already had has changed, and you can try again.

Run it a second time and it reports that everything is already here. That is safe at any point.

The demo has no images, because an image belongs to one organization. Its media section shows a labelled placeholder until you choose one.

  1. Upload an image in Assets, and make it public.
  2. In Content, open the Component Demo: picture and choose the image in its Media field.
  1. Open Composer and find the site named ebitex demo.
  2. Publish its root. The demo’s Components publish with it.

Publishing is what makes content visible to a delivery key. See Publishing for how a publish chooses what to freeze.

A site’s JavaScript is public, so use a browser-safe key restricted to the origins the site runs on, such as http://localhost:5190 while you try it out. Create a browser-safe delivery key explains the two kinds of key and why a browser-safe one is safe to ship.

The starter kit has a React renderer, published as @ebitex/starter-kit-react and also as a complete site in the public samples repository. It reads your organization through @ebitex/content-sdk and draws every section, theme and appearance with Tailwind CSS.

Terminal window
git clone https://github.com/ebitex-io/samples.git
cd samples/samples/starter-kit
cp .env.example .env

Set your delivery key in .env:

Terminal window
VITE_CONTENT_DELIVERY_KEY=your-browser-safe-key

Then install and start it:

Terminal window
npm install
npm run dev

Open http://localhost:5190. You should see the demo home page: a hero, a banner, an introduction, your image, three features, three cards, tabs, an accordion and a call to action. A switch in the corner changes the reader’s colour mode between system, light and dark.

If the page says content could not be loaded, check that the key’s allowed origins include http://localhost:5190, and that you published the site root.

To add the kit’s drawing to a site you already have, install the package beside the Content SDK:

Terminal window
npm install @ebitex/content-sdk @ebitex/starter-kit-react react-markdown remark-gfm

Import the tokens after Tailwind, and let Tailwind see the package’s classes:

@import "tailwindcss";
@import "@ebitex/starter-kit-react/styles.css";
@source "../node_modules/@ebitex/starter-kit-react/dist";

Then give the content provider the kit’s renderer:

quick-start.tsx
import { createContentClient } from '@ebitex/content-sdk'
import { ContentProvider, Experience } from '@ebitex/content-sdk/react'
import { EbitexMarkdown, EbitexProvider, Frame, SiteFooter, SiteHeader, ebitexRenderers, type EbitexRendererProps } from '@ebitex/starter-kit-react/react'
import { keyOf, pick, THEMES } from '@ebitex/starter-kit-react'
// A browser-safe delivery key, restricted to the origins this site runs on.
const content = createContentClient({ apiKey: 'your-browser-safe-key' })
// Replace how one Template is drawn, or draw a Template of your own. A renderer is chosen by the Template's external id, and receives the SDK's props: the Template's
// settings (width, background, appearance and so on, as categories) and the Contract's editorial fields in component.content. Drawing inside Frame gives the Template its
// own frame and joins the appearance cascade.
function MyCallToAction({ settings, component }: EbitexRendererProps) {
return (
<Frame settings={settings}>
<aside>
<h2>{String(component.content.heading)}</h2>
</aside>
</Frame>
)
}
export function App({ pathname }: { pathname: string }) {
return (
// Give the provider the same client: it fetches the site header and footer (the Site chrome Component) with it. Without a client no chrome is drawn.
<EbitexProvider client={content}>
<ContentProvider client={content} renderers={{ ...ebitexRenderers(), 'ebitex-cta-template': MyCallToAction }} markdown={EbitexMarkdown}>
<Experience path={pathname} />
</ContentProvider>
</EbitexProvider>
)
}
// A site that draws its header and footer once, outside its routes (so they mount once across navigation), says so by drawing them itself;
// the experience then does not draw a second pair.
export function Shell({ children }: { children: React.ReactNode }) {
return (
<EbitexProvider client={content}>
<SiteHeader />
{children}
<SiteFooter />
</EbitexProvider>
)
}
// The category helpers are plain functions with no React. A delivered category carries its path (`ebitex-theme/dark`); the key after the
// slash is what a renderer maps. A key it does not know falls back to the first word.
export function themeOf(category: unknown): string {
return keyOf(category) ?? pick(category, THEMES)
}

Give EbitexProvider the same client as the content provider (client). It fetches the site header and footer with it, once per session, and the experience draws them around the page. The chrome is the Site chrome Component, so publish it too: publishing a page does not, because nothing on a page refers to it. A half that is not published draws nothing.

The package is meant to be outgrown a piece at a time:

To change Do
How one Template draws Replace its entry in the renderers map you give the content provider, keyed by the Template’s external id. The component receives the Template’s settings and the Component’s content.
A Template of your own Register it in the same map. Draw inside the kit’s Frame to get the Template’s width, background, anchor and appearance. A Template with no renderer shows the provider’s fallback and never breaks the page.
How links navigate Pass your router’s link as link. The default is a plain anchor.
The header or the footer Register your own renderer for ebitex-site-header-template or ebitex-site-footer-template, or draw SiteHeader and SiteFooter yourself outside your routes (the experience then draws no second pair), or pass chrome={false}.
A colour, a theme or an appearance Redefine the --ebitex-* tokens after the import, or copy a theme or appearance block from styles.css and edit it. A brand is five tokens: surface, ink, accent, accent-ink and line. --ebitex-font-display sets the face of the headings the kit draws.
Everything Run npx starter-kit-eject src/kit. It copies the components, tokens and category helpers into your project and never overwrites a file. Remove the package afterwards.

react-markdown and remark-gfm are only needed for EbitexMarkdown. Pass your own markdown component to the content provider to avoid them.

Everything below changes the site without code unless it says otherwise.

  • Change the words. Edit the demo’s Components, or delete them and build your own. Prose, buttons and headings are ordinary Component fields.
  • Group what belongs together. A Group puts a heading (and a small eyebrow) over any number of sections, and its settings set the spacing, the alignment and the appearance of the whole group. Set an appearance on the Group and everything inside takes it.
  • Brand the header and footer. Open the Site chrome Component: pick your logo from Assets, set the site name, links and button, and the Template settings for a sticky header and the logo’s size. Publish it.
  • Choose a theme. In Composer, open the ebitex demo page and set the Theme in its Template settings to default, dark or brand. A theme is chosen once for the whole experience, and an empty one means the default.
  • Give one section a different look. Where a section is placed, open its Template settings and set its Appearance: muted, inverted, brand or highlight. Inherit (the default) takes the parent’s, so a card in a grid follows the grid’s appearance unless it chooses its own.
  • Change layout, width, background, tone and emphasis the same way, in each placement’s settings.
  • Change how an accordion behaves. Its Template settings say whether one drawer is open at a time or they open independently, and which start open. The same accordion Component can behave differently on another page.
  • Edit the choices themselves. The values are categories, so you can rename them or add your own in Content under Categories.
  • Change the colours (code). Every colour in the renderer is a token in src/index.css. Change a token, or add a theme or an appearance by copying a block and editing it.
  • Teach it a category you added (code). The renderer reads each category’s key and maps it to its own classes in src/lib/vocab.ts. A key it does not know draws as the default until you add it there.
  • Add your own section type. Create a Contract that inherits the kit’s presentation base, a Template that supports it (with its own settings Contract, which can extend the kit’s section settings), and a renderer for the Template. Then add the Template to the experience’s Sections field in its Contract, which lists the Templates it accepts. A Template with no renderer shows the content provider’s fallback and never breaks a page.
  • Present the same content two ways. A second Template over the same Contract (a statement and a feature over the same heading, body and media) is better than a copy of the Contract: the words stay in one place, and each Template has its own renderer.
  • Change the Contracts. Add a field, remove one or rename one in Content like any other Contract. Content as code shows how to keep the model in a repository.

A theme or an appearance is a category. The Delivery API sends a category as a small descriptor with its group, its path (such as ebitex-theme/dark) and its display name, and nothing else. It does not send colours. So the renderer owns what a category means: the sample turns ebitex-theme/dark into a set of colour tokens, and ebitex-appearance/inverted into an override for one section. A different renderer can read the same content and map the same names to something else.

Each ebitex organization installs its own copy of the kit, so the work above is repeated per client, and a client’s changes never reach another’s. A practical pattern for an agency:

  1. Create the client’s organization and install the kit.
  2. Adapt the renderer once into your own site template, with your design system’s tokens.
  3. For each new client, install the kit, publish, create a key, and point a copy of your template at it.

Because the kit is only a starting point, your template is the part that carries over from client to client.

You see Cause and fix
The page says Assets has to be connected The kit’s media fields name Assets’ Contracts, which exist once Assets is connected. Use Connect Assets on the same page.
The page says you need permission It names what to ask for: managing Contracts, Templates or the organization’s categories.
Install the kit is disabled There is nothing to add (the kit is installed), a permission is missing, or Assets is not connected. The page says which.
The site shows content could not be loaded The key’s allowed origins do not include the address you opened, or nothing is published.
A grey Choose media in Assets box A media field has nothing chosen. Choose an image in the Component.
A section shows the provider’s fallback Its Template has no renderer registered. Register one in the renderers map.
A section you added is not offered in Sections The Sections field lists the Templates it accepts. Add your Template to it in the experience’s Contract.
The kit will not install The environment already holds an earlier version of the kit, which is never mixed with a new major version. Install into a new environment or organization.
A colour or layout does not change The category you chose is one the renderer does not map. Add it in src/lib/vocab.ts.