API
nextAdminRouter
function
nextAdminRouter
is a function that returns a promise of a Node Router that you can use in your getServerSideProps function to start using Next Admin.
Usage example:
// pages/api/admin/[[...nextadmin]].ts
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
const { nextAdminRouter } = await import(
"@premieroctet/next-admin/dist/router"
);
const adminRouter = await nextAdminRouter(prisma, schema);
return adminRouter.run(req, res) as Promise<
GetServerSidePropsResult<{ [key: string]: any }>
>;
};
It takes 3 parameters:
- Your Prisma client instance, _required
- Your Prisma schema, _required
and an optional object of type NextAdminOptions
to customize your admin with the following properties:
import { NextAdminOptions } from "@premieroctet/next-admin";
const options: NextAdminOptions = {
modelOptions: {
user: {
toString: (user) => `${user.email} / ${user.name}`,
},
},
};
const adminRouter = await nextAdminRouter(prisma, schema, options);
Authentication
The library does not provide an authentication system. If you want to add your own, you can do so by adding a role check to the getServerSideProps
function:
The following example uses next-auth (opens in a new tab) to handle authentication
// pages/api/admin/[[...nextadmin]].ts
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
const session = await getServerSession(req, res, authOptions);
const isAdmin = session?.user?.role === 'SUPERADMIN'; // your role check
if (!isAdmin) {
return {
redirect: {
destination: '/',
permanent: false,
},
};
}
const { nextAdminRouter } = await import(
'@premieroctet/next-admin/dist/nextAdminRouter'
);
return nextAdminRouter(client).run(req, res);
};
<NextAdmin />
component
<NextAdmin />
is a React component that contains the entire UI of Next Admin. It can take several props:
AdminComponentProps
, which are passed by the router function via getServerSidePropsoptions
used to customize the UI, like field formatters for exampledashboard
used to customize the rendered dashboard
⚠️ : Do not override these
AdminComponentProps
props, they are used internally by Next Admin.
This is an example of using the NextAdmin
component with a custom Dashboard component and options:
// pages/admin/[[...nextadmin]].tsx
import Dashboard from "../../components/CustomDashboard";
export default function Admin(props: AdminComponentProps) {
/* Props are passed from the nextAdminRouter function via getServerSideProps */
return <NextAdmin {...props} dashboard={Dashboard} options={{
model: {
user: {
list: {
fields: {
role: {
formatter: (user) => {
return <strong>{user.role as string}</strong>;
},
}
}
}
}
}
}} />;
}
Next Admin Options
Next Admin options is the third parameter of the router function and it's an object of options that has the following properties:
model
model
is an object that represents the customization options for each model in your schema.
It takes as key a model name of your schema as value an object to customize your it.
By default if no models are defined, they will all be displayed in the admin. If you want more control, you have to define each model individually as empty objects or with the following properties:
Name | Description | Default value |
---|---|---|
fields | an object that define options for the fields of your model | undefined |
toString | a function that is used to display your record in related list | id field |
You can customize the following for each model:
This property determines how your data is displayed in the List View
You can disable a feature for any field in the fields
that follow this form:
Name | Description | Default value |
---|---|---|
search | a boolean that define wether this field is searchable | true |
display | a boolean that define wether this field should be visible in the list view | true (*) |
Note that the
search
property is only available forscalar
fields.
(*) If
display
isn't set anywhere, all fields are displayed; once you set a display property to true, all fields are hidden by default except the ones you set to `display: true.
💡 By default, all fields are searchable and visible, use the
list
property to return a limited subset of fields instead of all fields in the list view.
This property determines how your data is displayed in the edit view
You can disable a property for any field in the fields
that follow this form:
Name | Description | Default value |
---|---|---|
display | a boolean that define whether this field should be editable | true (*) |
validate | a function to validate on the server the form value. It should returns true or the error message | undefined |
(*) If
display
is not set anywhere, all fields are displayed; once you set a display property to true, all fields are hidden by default except the ones you've set todisplay: true
.
💡 By default all fields are searchable and visible, use the
edit
property to return a limited subset of fields instead of all fields in the edit view.
Here is an example of using NextAdminOptions
for the following schema :
// prisma/schema.prisma
enum Role {
USER
ADMIN
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
password String @default("")
posts Post[] @relation("author") // One-to-many relation
profile Profile? @relation("profile") // One-to-one relation
birthDate DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
role Role @default(USER)
}
// pages/api/admin/[[...nextadmin]].ts
const options: NextAdminOptions = {
model: {
user: {
toString: (user) => `${user.name} (${user.email})`,
list: {
fields: {
id: {
search: true,
display: true,
},
name: {
search: true,
display: true,
},
email: {
search: true,
display: true,
},
role: {
search: true,
display: true,
},
posts: {
search: true,
display: true,
},
},
},
edit: {
fields: {
id: {
display: true,
},
name: {
display: true,
},
email: {
display: true,
validate: (email) => email.includes("@") || "Invalid email",
},
role: {
display: true,
},
posts: {
display: true,
},
profile: {
display: true,
},
},
},
},
},
};
const adminRouter = await nextAdminRouter(prisma, schema, options);
Why do we have
@ts-expect-error
comments in the code above? We don't know if a relational field belongs to a model because of the Prisma type constraint. So if you want to use a relational field in thefields
property, you need to add the@ts-expect-error
comment to avoid TypeScript errors.