submitly

submitly/next

The Next.js App Router preset for CrudProvider.

import { NextCrudProvider, isNextInterrupt } from "submitly/next";

Client-side Next.js integration. It is a client module ("use client"), so NextCrudProvider can be imported straight into a Server Component layout. It needs next >= 15 as a peer dependency. The server half is documented in submitly/next/server.

NextCrudProvider

function NextCrudProvider(props: NextCrudProviderProps): JSX.Element;

A CrudProvider preset for the App Router:

PropPreset value
onMutatedrouter.refresh(), or a no-op when refreshOnMutated is false
navigaterouter.push(to)
isInterruptisNextInterrupt

Any prop you pass wins over the preset. Props that are undefined are ignored, so they never erase a preset value.

Functions cannot be passed from a Server Component to a Client Component. From a Server Component, pass only serializable props (such as refreshOnMutated). To pass notify, onMutated, navigate or other functions, wrap NextCrudProvider in your own "use client" component. The Next.js quick start shows the wrapper.

// app/layout.tsx (Server Component): only serializable props.
<NextCrudProvider refreshOnMutated={false}>{children}</NextCrudProvider>

NextCrudProviderProps

type NextCrudProviderProps = CrudProviderProps & {
  refreshOnMutated?: boolean;
};

Every CrudProviderProps prop (children, notify, onMutated, navigate, normalize, mapError, isInterrupt, onError) plus:

PropTypeDefaultDescription
refreshOnMutatedbooleantrueCall router.refresh() after each successful mutation. Turn it off when your server actions already revalidate (runAction with revalidate), which updates the UI in the same round trip. An explicit onMutated prop takes precedence over this flag.

isNextInterrupt

function isNextInterrupt(error: unknown): boolean;

True for Next.js control-flow errors: the errors thrown by redirect(), notFound(), forbidden() and unauthorized(). It is the preset's isInterrupt, exported so you can reuse it, for example in a CrudProvider that wraps part of a Next.js app with your own settings, or when composing your own isInterrupt:

<CrudProvider isInterrupt={(error) => isNextInterrupt(error) || error instanceof SessionExpiredError}>
Edit on GitHub

On this page