API
Functions
The following is used only for App router.
getPropsFromParams
function
getPropsFromParams
is a function that returns the props for the NextAdmin
component. It accepts one argument which is an object with the following properties:
params
: the array of route params retrieved from the optional catch-all segment (opens in a new tab)searchParams
: the query params retrieved from the page (opens in a new tab)options
: the options objectschema
: the json schema generated by theprisma generate
commandprisma
: your Prisma client instanceaction
: the server action (opens in a new tab) used to submit the form. It should be your own action, that wraps thesubmitForm
action imported from@premieroctet/next-admin/dist/actions
.deleteAction
: the server action (opens in a new tab) used to delete one or more records in a resource. It is optional, and should be your own action. This action takes 3 parameters:model
(the model name) andids
(an array of ids to delete). Next Admin provides a default action for deletion, that you can call in your own action. Check the example app for more details.getMessages
: a function with no parameters that returns translation messages. It is used to translate the default messages of the library. See i18n for more details.searchPaginatedResourceAction
: the server action (opens in a new tab) used to search for resources in a selector widget. This is mandatory for App Router, and will be ignored on page router. Just likeaction
, it should be your own action that wrapssearchPaginatedResource
imported from@premieroctet/next-admin/dist/actions
.
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 in the page:
The following example uses next-auth (opens in a new tab) to handle authentication
// app/admin/[[...nextadmin]]/page.tsx
export default async function AdminPage({
params,
searchParams,
}: {
params: { [key: string]: string[] };
searchParams: { [key: string]: string | string[] | undefined } | undefined;
}) {
const session = await getServerSession(authOptions);
const isAdmin = session?.user?.role === "SUPERADMIN"; // your role check
if (!isAdmin) {
redirect('/', { permanent: false })
}
const props = await getPropsFromParams({
params: params.nextadmin,
searchParams,
options,
prisma,
schema,
action: submitFormAction,
});
return <NextAdmin {...props} dashboard={Dashboard} />;
}
<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 example. Do not use with App router.dashboard
used to customize the rendered dashboardtranslations
used to customize some of the texts displayed in the UI. See i18n for more details.user
used to add some user information at the bottom of the menu. See user properties for more details.
⚠️ : 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: {
display: ["id", "name", "email", "posts", "role", "birthDate"],
search: ["name", "email"],
fields: {
role: {
formatter: (role) => {
return <strong>{role.toString()}</strong>;
},
},
birthDate: {
formatter: (date) => {
return new Date(date as unknown as string)
?.toLocaleString()
.split(" ")[0];
},
},
},
},
},
},
}}
/>
);
}
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:
basePath
basePath
is a string that represents the base path of your admin. (e.g. /admin
) - optional.
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 |
---|---|---|
toString | a function that is used to display your record in related list | id field |
aliases | an object containing the aliases of the model fields as keys, and the field name | undefined |
title | a string used to display the model name in the sidebar and in the section title | Model name |
list | an object containing the list options | undefined |
edit | an object containing the edit options | undefined |
actions | an array of actions | undefined |
icon | the outline HeroIcon name (opens in a new tab) displayed in the sidebar and pages title | undefined |
permissions | an array to specify restricted permissions on model | [create , edit , delete ] |
You can customize the following for each model:
This property determines how your data is displayed in the List View
Name | Description | Default value |
---|---|---|
search | an array of searchable fields | undefined - all scalar fields are searchable |
display | an array of fields that are displayed in the list | undefined - all scalar fields are displayed |
fields | an object containing the model fields as keys, and customization values, see below | undefined |
copy | an array of fields that are copyable into the clipboard | undefined - no field is copyable by default |
defaultSort | an optional object to determine the default sort to apply on the list | undefined |
defaultSort.field | the model's field name on which the sort is applied. It is mandatory | |
defaultSort.direction | the sort direction to apply. It is optional |
Note that the
search
property is only available forscalar
fields.
This property determines how your data is displayed in the edit view
Name | Description | Default value |
---|---|---|
display | an array of fields that are displayed in the form. It can also be an object that will be displayed in the form of a notice. See notice | all scalar fields are displayed |
styles | an object containing the styles of the form | undefined |
fields | an object containing the model fields as keys, and customization values | undefined |
submissionErrorMessage | a message displayed if an error occurs during the form submission, after the form validation and before any call to prisma | Submission error |
styles
property
The styles
property is available in the edit
property.
⚠️ If your options are defined in a separate file, make sure to add the path to the
content
property of thetailwind.config.js
file
Name | Description |
---|---|
_form | a string defining the classname of the form |
... | all fields of the model, with the field name as key and the classname as value |
Here is an example of using styles
property:
styles: {
_form: "form-classname",
... // all fields
};
fields
property
The fields
property is available in both list
and edit
properties.
For the list
property, it can take the following:
Name | Description |
---|---|
formatter | a function that takes the field value as a parameter, and that return a JSX node. It also accepts a second argument which is the NextAdmin context |
For the edit
property, it can take the following:
Name | Description |
---|---|
validate | a function that takes the field value as a parameter, and that returns a boolean |
format | a string defining an OpenAPI field format, overriding the one set in the generator. An extra file format can be used to be able to have a file input |
input | a React Element that should receive CustomInputProps. For App Router, this element must be a client component. |
handler | an object that can take the following properties |
handler.get | a function that takes the field value as a parameter and returns a transformed value displayed in the form |
handler.upload | an async function that is used only for formats file and data-url . It takes a buffer as parameter and must return a string. Useful to upload a file to a remote provider |
handler.uploadErrorMessage | an optional string displayed in the input field as an error message in case of a failure during the upload handler |
optionFormatter | only for relation fields, a function that takes the field values as a parameter and returns a string. Useful to display your record in related list |
tooltip | a tooltip content to show for the field |
helperText | a helper text that is displayed underneath the input |
disabled | a boolean to indicate that the field is read only |
display | only for relation fields, indicate which display format to use between list , table or select . Default select |
pages
pages
is an object that allows you to add your own sub pages as a sidebar menu entry. It is an object where the key is the path (without the base path) and the value is an object with the following properties:
Name | Description |
---|---|
title | the title of the page displayed on the sidebar |
icon | the outline HeroIcon name (opens in a new tab) of the page displayed on the sidebar |
actions
property
The actions
property is an array of objects that allows you to define a set of actions that can be executed on one or more records of the resource. On the list view, there is a default action for deletion. The object can take the following properties:
Name | Description | Default value |
---|---|---|
title | action title that will be shown in the action dropdown | undefined |
action | an async function that will be triggered when selecting the action in the dropdown. For App Router, it must be defined as a server action. | undefined |
successMessage | a message that will be displayed when the action is successful | undefined |
errorMessage | a message that will be displayed when the action fails | undefined |
sidebar
property
The sidebar
property allows you to customise the aspect of the sidebar menu. It is an object that can take the following properties:
Name | Description | Default value |
---|---|---|
groups | an array of objects that creates groups for specific resources. It takes the following properties : | |
groups[].title | the name of the group | |
groups[].models | the model names to display in the group |
externalLinks
property
The externalLinks
property allows you to add external links to the sidebar menu. It is an array of objects that can take the following properties:
Name | Description |
---|---|
label | the label of the link displayed on the sidebar. This is mandatory |
url | the URL of the link. This is mandatory |
defaultColorScheme
property
The defaultColorScheme
property defines a default color palette between light
, dark
and system
, but allows the user to modify it. Default to system
.
forceColorScheme
property
Identical to defaultColorScheme
but does not allow the user to change it.
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 = {
basePath: "/admin",
model: {
User: {
toString: (user) => `${user.name} (${user.email})`,
list: {
display: ["id", "name", "email", "posts", "role", "birthDate"],
search: ["name", "email"],
fields: {
role: {
formatter: (role) => {
return <strong>{role.toString()}</strong>;
},
},
birthDate: {
formatter: (date) => {
return new Date(date as unknown as string)
?.toLocaleString()
.split(" ")[0];
},
},
},
},
edit: {
display: ["id", "name", "email", "posts", "role", "birthDate"],
fields: {
email: {
validate: (email) => email.includes("@") || "Invalid email",
},
birthDate: {
format: "date",
},
avatar: {
format: "file",
handler: {
upload: async (file: Buffer) => {
return "https://www.gravatar.com/avatar/00000000000000000000000000000000";
},
},
},
},
},
},
},
};
const adminRouter = await nextAdminRouter(prisma, schema, options);
CustomInputProps
This is the type of the props that are passed to the custom input component:
Name | Description |
---|---|
name | the field name |
value | the field value |
onChange | a function taking a ChangeEvent (opens in a new tab) as a parameter |
readonly | boolean indicating if the field is editable or not |
rawErrors | array of strings containing the field errors |
disabled | boolean indicating if the field is disabled |
NextAdmin Context
The NextAdmin
context is an object containing the following properties:
locale
: the locale used by the calling page. (refers to theaccept-language
header).
Notice
The edit page's form can display notice alerts. To do so, you can pass objects in the display
array of the edit
property of a model. This object takes the following properties :
Name | Description |
---|---|
title | The title of the notice. This is mandatory |
id | A unique identifier for the notice that can be used to style it with the styles property. This is mandatory |
description | The description of the notice. This is optional |
User properties
The user
property is an object that can take the following properties:
Name | Description |
---|---|
data.name | the name of the user displayed in the sidebar menu. This is required |
data.picture | the URL of the user's avatar displayed in the sidebar menu |
logoutUrl | an URL or path to logout the user. This is required. |