# Getting Started

<Callout type="info">
  This is the documentation for the latest version of Next Admin. If you are using an older version (`<5.0.0`), please refer to the [documentation](https://next-admin.js.org/v4/docs/getting-started)
</Callout>

The following guide will help you get started with Next-Admin.

<Tabs items={["CLI", "Manually"]}>

<Tabs.Tab>

<Callout type="info">
  The CLI is in its early stages of development and might be the subject of
  unexpected behaviors. If you encounter any issues, please report them on the
  [GitHub repository](https://github.com/premieroctet/next-admin/issues). **CLI currently only supports
  Next.js projects.**
</Callout>

You can initialize the required files to use Next-Admin in your project using the CLI.

```bash
npx @premieroctet/next-admin-cli@latest init
```

Make sure to check the available options by running the following command:

```bash
npx @premieroctet/next-admin-cli@latest init --help
```

</Tabs.Tab>

<Tabs.Tab>
<Steps>
### Installation

<Tabs items={["yarn", "npm", "pnpm"]}>
  <Tabs.Tab>
    ```bash copy
yarn add @premieroctet/next-admin @premieroctet/next-admin-generator-prisma
    ```

  </Tabs.Tab>
  <Tabs.Tab>
    ```bash copy
npm install -S @premieroctet/next-admin @premieroctet/next-admin-generator-prisma
    ```
  </Tabs.Tab>
  <Tabs.Tab>
    ```bash copy
pnpm add @premieroctet/next-admin @premieroctet/next-admin-generator-prisma
    ```
  </Tabs.Tab>
</Tabs>

### TailwindCSS

Next-Admin relies on [TailwindCSS](https://tailwindcss.com/) for the style. If you do not have it, you can [install TailwindCSS](https://tailwindcss.com/docs/installation) with the following configuration :

<Tabs items={["v4", "<=v3"]}>
<Tabs.Tab>
```css copy filename="styles.css"
@import "tailwindcss";
@import "@premieroctet/next-admin/theme";
@source "./node_modules/@premieroctet/next-admin/dist";
```
</Tabs.Tab>
<Tabs.Tab>
```javascript copy filename="tailwind.config.js"
module.exports = {
  content: [
    "./node_modules/@premieroctet/next-admin/dist/**/*.{js,ts,jsx,tsx}",
  ],
  darkMode: "class",
  presets: [require("@premieroctet/next-admin/preset")],
};
```
</Tabs.Tab>
</Tabs>

Then import your `.css` file containing Tailwind rules into a page file or a parent layout.

You can find more information about theming [here](https://next-admin.js.org/docs/theming)

### Prisma

Next-Admin relies on [Prisma](https://www.prisma.io/) for the database. If you do not have it, you can [install Prisma](https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch-typescript-postgres) with the following config.

You have to add the `jsonSchema` generator to your `schema.prisma` file:

```prisma copy filename="schema.prisma"
generator nextAdmin {
  provider = "next-admin-generator-prisma"
}
```

<Callout emoji="⚠️">
    If you use the [new Prisma Client generator](https://www.prisma.io/docs/orm/prisma-schema/overview/generators#prisma-client-early-access), make sure
    the Next-Admin generator is placed AFTER the Prisma Client generator. This is because the Next-Admin generator makes a copy of the generated client inside
    Next-Admin's `dist` folder.
</Callout>

Then run the following command :

```bash copy
yarn run prisma generate
```

<Tabs items={['Next.js', 'Other frameworks']}>

<Tabs.Tab>
### Page `[[...nextadmin]]`

Next-Admin uses a dynamic route `[[...nextadmin]]` to handle all the admin routes.

<Tabs items={['App router', 'Pages router']}>
  <Tabs.Tab>

    #### Create file : `page.tsx`

    ```tsx copy filename="app/admin/[[...nextadmin]]/page.tsx"
    import { PageProps } from "@premieroctet/next-admin";
    import { getNextAdminProps } from "@premieroctet/next-admin/appRouter";
    import { NextAdmin } from "@premieroctet/next-admin/adapters/next";
    import { prisma } from "@/prisma";
    import "@/styles.css" // .css file containing tailiwnd rules

    export default async function AdminPage({
      params,
      searchParams,
    }: PageProps) { // or PromisePageProps for Next 15+
      const props = await getNextAdminProps({
        params: params.nextadmin,
        searchParams,
        basePath: "/admin",
        apiBasePath: "/api/admin",
        prisma,
        /*options*/
      });

      return (
        <NextAdmin {...props} />
      );
    }
    ```

    <Callout emoji="⚠️">

      Passing the `options` prop like you'd do on Pages router will result in an error in case you
      have functions defined inside the options object (formatter, handlers, etc.).
      Make sure to pass no `options` prop to `NextAdmin` component in App router.

    </Callout>

    <Callout emoji="⚠️">
      Make sure to not use `use client` in the page.
    </Callout>

    <Callout emoji="⚠️">
      Because we are using [next-themes](https://github.com/pacocoursey/next-themes) to handle dark mode,
      you will need to add the `suppressHydrationWarning` to your the closest `<html>` tag of the admin page.
      See [the next-themes docs](https://github.com/pacocoursey/next-themes?tab=readme-ov-file#with-app)
    </Callout>

  </Tabs.Tab>
  <Tabs.Tab>

    #### Create file : `[[...nextadmin]].ts`

    ```tsx copy filename="pages/admin/[[...nextadmin]].ts"
    import { AdminComponentProps } from "@premieroctet/next-admin";

    import { getNextAdminProps } from "@premieroctet/next-admin/pageRouter";
    import { NextAdmin } from "@premieroctet/next-admin/adapters/next";
    import { GetServerSideProps } from "next";
    import { prisma } from " @/prisma";

    export default function Admin(props: AdminComponentProps) {
      return (
        <NextAdmin {...props} />
      );
    }

    export const getServerSideProps: GetServerSideProps = async ({ req }) =>
      await getNextAdminProps({
        basePath: "/pagerouter/admin",
        apiBasePath: "/api/pagerouter/admin",
        prisma,
        /*options*/
        url: req.url!,
      });
    ```

    <Callout type="info">
      Do not forget to add the `options` prop to `<NextAdmin />` component and `getNextAdminProps` function, if you are using it.
    </Callout>
    <Callout type="info">
      Your CSS file should be imported in the `_app.js` / `_app.tsx` file. This is mandatory per the [Next.js documentation](https://nextjs.org/docs/messages/css-global). In most apps, you might have a different tailwind configuration living with the Next-Admin one. In that case, to avoid any conflicts, you can create an [App Router layout file](https://nextjs.org/docs/app/building-your-application/routing/layouts-and-templates#layouts) which imports the CSS file.
    </Callout>

    #### SuperJson configuration

SuperJson is required to avoid errors related to invalid serialisation properties that can occur when passing data from server to client.

##### With Babel

<Tabs items={["yarn", "npm", "pnpm"]}>
  <Tabs.Tab>
    ```bash
      yarn add -D babel-plugin-superjson-next superjson@^1
    ```

  </Tabs.Tab>
  <Tabs.Tab>
    ```bash
      npm install --save-dev babel-plugin-superjson-next superjson@^1
    ```
  </Tabs.Tab>
  <Tabs.Tab>
    ```bash
      pnpm install -D babel-plugin-superjson-next superjson@^1
    ```
  </Tabs.Tab>
</Tabs>

Add the `babel-plugin-superjson-next` plugin to your `.babelrc` file:

```json
{
  "presets": ["next/babel"],
  "plugins": ["superjson-next"]
}
```

##### With SWC (Experimental)

<Tabs items={["yarn", "npm", "pnpm"]}>
  <Tabs.Tab>
    ```bash
yarn add -D next-superjson-plugin superjson
    ```

  </Tabs.Tab>
  <Tabs.Tab>
    ```bash
npm install --save-dev next-superjson-plugin superjson
    ```
  </Tabs.Tab>
  <Tabs.Tab>
    ```bash
pnpm install -D next-superjson-plugin superjson
    ```
  </Tabs.Tab>
</Tabs>

Add the `next-superjson-plugin` plugin to your `next.config.js` file:

```js
module.exports = {
  // your current config
  experimental: {
    swcPlugins: [
      [
        "next-superjson-plugin",
        {
          excluded: [],
        },
      ],
    ],
  },
};
```

  </Tabs.Tab>

More information about the `getNextAdminProps` [here](https://next-admin.js.org/docs/api/get-next-admin-props-function).

</Tabs>

### API Route `[[...nextadmin]]`

Next-Admin uses a dynamic route `[[...nextadmin]]` to handle all the API routes.

<Tabs items={['App router', 'Pages router']}>
  <Tabs.Tab>

    ```ts copy filename="app/api/admin/[[...nextadmin]]/route.ts"
    import { prisma } from "@/prisma";
    import { createHandler } from "@premieroctet/next-admin/appHandler";

    const { run } = createHandler({
      apiBasePath: "/api/admin",
      prisma,
      /*options*/
    });

    export { run as DELETE, run as GET, run as POST };
    ```

  </Tabs.Tab>
  <Tabs.Tab>

      ```ts copy filename="pages/api/admin/[[...nextadmin]].ts"
      import { prisma } from "@/prisma";
      import { createHandler } from "@premieroctet/next-admin/pageHandler";

      export const config = {
        api: {
          bodyParser: false,
        },
      };

      const { run } = createHandler({
        apiBasePath: "/api/admin",
        prisma,
        /*options*/,
      });

      export default run;
      ```

      <Callout emoji="⚠️">
        Make sure to export the config object to define no `bodyParser`. This is required to be able to parse FormData.
      </Callout>

  </Tabs.Tab>

More information about the `createHandler` function [here](https://next-admin.js.org/docs/api/create-handler-function).

</Tabs>

</Tabs.Tab>

<Tabs.Tab>

### Page splat route

Next-Admin uses [splat routes](https://remix.run/docs/en/main/file-conventions/routes#splat-routes) to handle all the admin routes. Its implementation depends on your framework. Examples are available on the repository.

The page should load data using the `getNextAdminProps` function. Here is an example for Remix :

```tsx
import { AdminComponentProps } from "@premieroctet/next-admin";
import { NextAdmin } from "@premieroctet/next-admin/adapters/remix";
import { getNextAdminProps } from "@premieroctet/next-admin/pageRouter";
import { LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import prisma from "database";
import { options } from "../options";

export const loader = async ({ request }: LoaderFunctionArgs) => {
  return getNextAdminProps({
    url: request.url,
    apiBasePath: "/api/admin",
    basePath: "/admin",
    prisma,
    options,
  });
};

export default function Admin() {
  const data = useLoaderData<typeof loader>();

  return (
    <NextAdmin {...(data.props as AdminComponentProps)} />
  );
}
```

### API splat route

Next-Admin uses [splat routes](https://remix.run/docs/en/main/file-conventions/routes#splat-routes) to handle all the API routes. Its implementation depends on your framework.

You should use the `createHandler` function provided for Next.js App Handler which provides support for web Request and Response. Here is an example implementation for Remix :

```tsx
import { createHandler } from "@premieroctet/next-admin/appHandler";
import { LoaderFunctionArgs } from "@remix-run/node";
import prisma from "database";
import { options } from "../options";

const nextAdminApi = createHandler({
  prisma,
  apiBasePath: "/api/admin",
  options,
});

// For GET requests
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
  return nextAdminApi.run(request, {
    params: Promise.resolve({
      nextadmin: params["*"]!.split("/"),
    }),
  });
};

// For POST, PUT & DELETE requests
export const action = async ({ request, params }: LoaderFunctionArgs) => {
  return nextAdminApi.run(request, {
    params: Promise.resolve({
      nextadmin: params["*"]!.split("/"),
    }),
  });
};
```

</Tabs.Tab>

</Tabs>

### Next Admin options - optional

The `NextAdmin` component accepts an optional `options` prop. In the blocks above, you can see that the `options` prop is commented out. It may be useful to centralize the options in a single file. More information about the options [here](https://next-admin.js.org/docs/api/options).

<Callout type="info">
  The `options` parameter can be set to function/component, if you are using
  options, be sure to pass the same options to the handler and the router
  function.
</Callout>

</Steps>
</Tabs.Tab>

</Tabs>

### Usage

Once done, you can navigate to the `/admin` route.
