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

# CMS

> How the CMS is configured in JTBDOS.

export const Authors = ({data}) => {
  const baseUrl = typeof window !== 'undefined' && window.location.origin.includes('localhost') ? '' : 'https://raw.githubusercontent.com/haydenbleasel/JTBDOS/refs/heads/main/docs';
  return <div style={{
    marginBottom: '3rem',
    display: 'flex',
    flexDirection: 'column',
    gap: '0.5rem'
  }}>
      <span style={{
    color: 'rgb(107, 114, 128)',
    fontSize: '0.875rem'
  }}>Co-authored by</span>
      <div style={{
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'center',
    gap: '0.5rem'
  }}>
        {data.map(author => <div key={author.name} style={{
    padding: '0.75rem',
    paddingRight: '1rem',
    display: 'inline-flex',
    alignItems: 'center',
    gap: '0.75rem',
    fontWeight: 'normal',
    position: 'relative',
    ringWidth: '2px',
    ringColor: 'transparent',
    borderRadius: '0.75rem',
    backgroundColor: 'white',
    border: '1px solid rgba(0,0,0,0.1)',
    overflow: 'hidden'
  }}>
            <div style={{
    position: 'relative'
  }}>
              <div style={{
    overflow: 'hidden',
    border: '1px solid #e5e7eb',
    borderRadius: '9999px',
    width: '2rem',
    height: '2rem'
  }}>
                <img style={{
    margin: 0,
    width: '100%',
    height: '100%',
    objectFit: 'cover'
  }} src={`${baseUrl}/images/authors/${author.company.id}/${author.user.id}.jpg`} alt="" width={32} height={32} />
              </div>
              <div style={{
    position: 'absolute',
    border: '1px solid white',
    overflow: 'hidden',
    borderRadius: '9999px',
    objectFit: 'cover',
    width: '1rem',
    height: '1rem',
    right: '-0.25rem',
    bottom: '-0.25rem'
  }}>
                <img style={{
    margin: 0,
    width: '100%',
    height: '100%',
    objectFit: 'cover'
  }} src={`${baseUrl}/images/authors/${author.company.id}/logo.jpg`} alt="" width={16} height={16} />
              </div>
            </div>
            <div style={{
    display: 'flex',
    flexDirection: 'column'
  }}>
              <span style={{
    fontWeight: 600,
    lineHeight: 1.25,
    fontSize: '13px',
    letterSpacing: '-0.01em'
  }}>
                {author.user.name}
              </span>
              <span style={{
    color: 'rgb(107, 114, 128)',
    lineHeight: 1.25,
    fontSize: '11px'
  }}>
                {author.company.name}
              </span>
            </div>
          </div>)}
      </div>
    </div>;
};

<Authors
  data={[
{
  user: {
    name: "Hayden Bleasel",
    id: "haydenbleasel",
  },
  company: {
    name: "JTBDOS",
    id: "JTBDOS",
  },
},
{
  user: {
    name: "Julian Benegas",
    id: "julianbenegas8",
  },
  company: {
    name: "BaseHub",
    id: "basehub",
  },
},
]}
/>

JTBDOS has a dedicated CMS package that can be used to generate type-safe data collections from your content. This approach provides a structured way to manage your content while maintaining full type safety throughout your application.

By default, JTBDOS uses [BaseHub](https://basehub.com) as the CMS. However, it is also possible to use other sources, such as [Content Collections](/migrations/cms/content-collections) to generate type-safe data collections from MDX files.

## Setup

Here's how to quickly get started with your new CMS.

### 1. Fork the [`basehub/JTBDOS`](https://basehub.com/basehub/JTBDOS?fork=1) template

You'll be forking a BaseHub repository which contains the JTBDOS compatible content schema.

Once you fork the repository, you'll need to get your Read Token from the "Connect to your App" page:

```
https://basehub.com/<team-slug>/<repo-slug>/dev/main/dev:connect
```

The token will look something like this:

```
bshb_pk_<password>
```

Keep this connection string handy, you will need it in the next step.

### 2. Update your environment variables

Update your [environment variables](/env) to use the new BaseHub token. For example:

```ts apps/web/.env
BASEHUB_TOKEN="<token>"
```

## How it works

### The `Feed` component

The `Feed` component is a wrapper around BaseHub's `Pump` component — a React Server Component that gets generated with the basehub SDK. It leverages RSC, Server Actions, and the existing BaseHub client to subscribe to changes in real time with minimal development effort.

It's also setup by default to use Next.js [Draft Mode](https://nextjs.org/docs/app/building-your-application/configuring/draft-mode), allowing you to preview draft content in your app.

### The `Body` component

The `Body` component is a wrapper around BaseHub's `RichText` component — BaseHub's rich text renderer which supports passing custom handlers for native html elements and BaseHub components.

### The `TableOfContents` component

The `TableOfContents` component leverages the `Body` component to render the table of contents for the current page.

### The `Image` component

The `Image` component is a wrapper around BaseHub's `BaseHubImage` component, which comes with built-in image resizing and optimization. BaseHub recommendeds using the `BaseHubImage` component instead of the standard Next.js `Image` component as it uses `Image` under the hood, but adds a custom loader to leverage BaseHub's image pipeline.

## The `Toolbar` component

The `Toolbar` component is a wrapper around BaseHub's `Toolbar` component, which helps manage draft mode and switch branches in your site previews. It's automatically mounted on CMS pages.
