# Project structure

The folders of AdminKit for React: index.html, the routes in src/routes, components, data, hooks and Sass, and how to add a page and its sidebar link.

AdminKit for React is a Vite app with one file per page. This page shows where things live, how a URL finds its page and how to add a page of your own.

The free and PRO versions use the same folders. AdminKit PRO has more pages, components and plugins in them.

```text
├── index.html              the page shell: head scripts, <body> attributes, #root
├── public/                 images and other files served as they are
├── scripts/                stats.mjs (npm run stats)
├── src/
│   ├── main.tsx            renders <App /> and imports the stylesheet
│   ├── app.tsx             the router: one route per entry in data/pages.json
│   ├── routes/             one file per page, named after its URL (index.tsx is /)
│   ├── components/
│   │   ├── bootstrap/      Modal, Dropdown, Offcanvas, ... (see Components)
│   │   ├── plugins/        ChartJs, VectorMap, ... (see Charts)
│   │   ├── navbar/         the top bar and its menus
│   │   ├── sidebar/        the sidebar and its menu
│   │   ├── settings/       the settings panel (PRO)
│   │   ├── ui/             PageTitle, CountUp, Skeleton, Footer
│   │   └── pages/          what one page uses, in pages/<section>/<page>/
│   ├── contexts/           LayoutProvider: the sidebar toggle
│   ├── data/               pages.json, navigation.ts, stats.json and the other app data
│   ├── hooks/              useColorMode, useTheme, useConfig (PRO), ...
│   ├── layouts/            DashboardLayout, AuthLayout, PageMeta and PageEffects
│   ├── lib/                config.ts, site.ts
│   ├── mocks/              the demo data of the pages
│   └── scss/               app.scss and the Sass partials
└── vite.config.ts          the build and BASE_PATH
```

## Routes

`src/app.tsx` builds the routes from `src/data/pages.json`. Each entry has a `path`, a `title`, a meta `description` and a `layout`. The layout is `"dashboard"` for pages with the sidebar, navbar and footer, or `"auth"` for the centered sign-in and error pages.

The page for a path is the file of the same name in `src/routes/`: `/pages-settings` is `src/routes/pages-settings.tsx`. The app loads it with `React.lazy` the first time someone opens it. Paths that match no route show the 404 page.

A page is a component, exported as default:

```tsx title="src/routes/pages-blank.tsx"
import { PageTitle } from "@/components/ui/page-title";

export default function Page() {
  return (
    <>
      <PageTitle title="Blank Page" />

      <div className="row">
        <div className="col-12">
          <div className="card">
            <div className="card-header">
              <h2 className="card-title mb-0">Empty card</h2>
            </div>
            <div className="card-body"></div>
          </div>
        </div>
      </div>
    </>
  );
}
```

`PageMeta` (`src/layouts/page-meta.tsx`) sets the document title and meta description of the current route from `pages.json`. Demo data lives in `src/mocks/`. Replace it with your own data, for example fetched in an effect or with your data library.

## Add a page

1. Create `src/routes/reports.tsx` from the blank page above.
2. Add it to `src/data/pages.json`:

   ```json
   {
     "path": "/reports",
     "title": "Reports",
     "layout": "dashboard",
     "description": "Monthly reports."
   }
   ```

3. Link it in the sidebar menu in `src/data/navigation.ts` (see [Sidebar](/react/docs/layout/sidebar/)).
4. Run `npm run stats`. It updates the counts in `src/data/stats.json`, and `npm run lint` fails while a file in `src/routes/` is missing from `pages.json` or the counts are out of date.

## Page title

Every dashboard page starts with a heading that tells people where they are. `PageTitle` renders it: one `<h1>` with the page's name. The free and PRO versions both have it, each with its own badge. You can see it on the [blank page demo](https://react-demo.adminkit.io/pages-blank).

`PageTitle` sets the visible heading only. The document `<title>` in the browser tab comes from `PageMeta`, as [Document title](#document-title) explains.

```html
<h1 class="h3 mb-3">Reports</h1>
```
```tsx code
import { PageTitle } from "@/components/ui/page-title";

export default function Page() {
  return (
    <>
      <PageTitle title="Reports" />
      {/* the page */}
    </>
  );
}
```

This is the AdminKit PRO output. The free version always adds a badge, as [Badges](#badges) shows.

The component is in `src/components/ui/page-title.tsx`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `title` | `string` | | The heading text |
| `pro` (PRO) | `boolean` | | Adds a "Pro Component" badge that links to the AdminKit pricing page |
| `badge` (free version) | `string` | `"Get more demos"` | The text of the badge that links to `/upgrade-to-pro` |

### Badges

The badges are part of the demo, and you will likely remove them in your app. In the free version, the badge links to the upgrade page of the demo:

```html
<div class="mb-3">
  <h1 class="h3 d-inline align-middle">Chart.js</h1>
  <a class="badge bg-dark text-light ms-2 d-print-none" href="#">Get more chart examples</a>
</div>
```
```tsx code
<PageTitle title="Chart.js" badge="Get more chart examples" />
```

The free `PageTitle` renders the badge with React Router's `Link`. To drop it in your app, change the component to return the heading only:

```tsx title="src/components/ui/page-title.tsx"
export function PageTitle({ title }: { title: string }) {
  return <h1 className="h3 mb-3">{title}</h1>;
}
```

In AdminKit PRO, `pro` marks the demo pages of PRO components. Leave it out on your own pages.

```html
<div class="mb-3">
  <h1 class="h3 d-inline align-middle">ApexCharts</h1>
  <a class="badge bg-primary ms-2" href="https://adminkit.io/pricing/" target="_blank">Pro Component <i class="fas fa-fw fa-external-link-alt"></i></a>
</div>
```
```tsx code
<PageTitle title="ApexCharts" pro />
```

### Document title

The browser tab, the history and screen readers use the document title, not the heading. `PageMeta` sets it, together with the `<meta name="description">`, each time the route changes. It reads both from the route's entry in `src/data/pages.json`. `PageMeta` is in `src/layouts/page-meta.tsx`, and `src/app.tsx` renders it once:

```json title="src/data/pages.json"
{
  "path": "/reports",
  "title": "Reports",
  "layout": "dashboard",
  "description": "Monthly sales and traffic reports."
}
```

The title becomes `Reports | AdminKit Demo`. The home page (`/`) keeps the site title, `AdminKit Demo - React Admin Template`, with its own description from `pages.json`. A path that is not in `pages.json` gets the site title and the site description. `site.title`, `site.slogan` and `site.description` are in `src/lib/site.ts`. The title and description in `index.html` show until the app starts.

Keep the `title` in `pages.json` and the `title` of `PageTitle` the same, so the tab and the heading match.

A few points keep the page title accessible:

- `PageTitle` renders the page's only `<h1>`, styled as `.h3`. Use `<h2>` for card titles below it, as the demo pages do.
- `PageMeta` gives every route its own document title, which screen readers announce and browser tabs and history show.
- The PRO badge opens a new tab (`target="_blank"`) without saying so. If you keep a link like it, say so in its text.

## Images and links

Use React Router's `Link` (`import { Link } from "react-router"`) for links between pages. Images are plain `<img>` elements with a `width` and `height`. Write their `src` with `asset()` from `src/lib/site.ts`, so they keep working under a [base path](/react/docs/getting-started/deployment/#base-path):

```tsx
<img src={asset("/img/avatars/avatar.jpg")} width="40" height="40" alt="" />
```

## Imports

`@/` is `src/` (set in `vite.config.ts` and `tsconfig.json`): `@/components/bootstrap/modal` is `src/components/bootstrap/modal.tsx`.

---

Canonical HTML page: https://adminkit.io/react/docs/getting-started/project-structure/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
