Blitz does not require any breaking changes with the major upgrade of Next 12
âž” Next 13
for usage with the pages
directory. You can even continue to use the old blitz layout with all your files in app
. But you'll need to rename that directory if you want to use the new Next.js app router.
The migration guide provided by the Next.js Team can then be followed to completely upgrade your Next 12 application
https://nextjs.org/docs/upgrading#upgrading-from-12-to-13
https://nextjs.org/docs/advanced-features/codemods
To support the new paradigm of Next that uses React Server Side Components,
the following methods and hooks have been implemented to work in the new app
directory
Add the new use client
directive to the following files:
src/blitz-client.(ts|js)
useQuery
, useInfiniteQuery
, usePaginatedQuery
, useMutation
, Hydrate
and other React Query client side hooks.What not to change:
/pags/api/rpc/[[...blitz]].ts
stays in the /pages
folder.
/src/pages
it is recommended to colocate the app directory at /src/app
. However, a root /app
App directory is also supported. More on the new NextJS file structure at "Project Organization and File Colocation".This provider should wrap the app and should be placed at the (root)/layout.ts
file.
Setup
// src/blitz-client.ts
"use client"
import {AuthClientPlugin} from "@blitzjs/auth"
import {setupBlitzClient} from "@blitzjs/next"
import {BlitzRpcPlugin} from "@blitzjs/rpc"
import { authConfig } from './blitz-auth-config'
export const {withBlitz, BlitzProvider} = setupBlitzClient({
plugins: [
AuthClientPlugin(authConfig),
BlitzRpcPlugin({}),
],
})
The authConfig
needs to be in a separate file that is imported in blitz-client.ts
as well as blitz-server.ts
:
// src/blitz-auth-config.ts
import { AuthPluginClientOptions } from '@blitzjs/auth'
export const authConfig: AuthPluginClientOptions = {
cookiePrefix: "blitz-auth-with-next-app",
}
In root layout.ts file
// src/layout.ts
import { BlitzProvider } from "src/blitz-client"
export default function RootLayout({children}: {children: React.ReactNode}) {
return (
<html lang="en">
<head>
...
</head>
<body>
<BlitzProvider>
...
</BlitzProvider>
</body>
</html>
)
}
This function will use the cookies and headers provided by the server component and returns the current session.
getBlitzContext() => Ctx
Example Usage in React Server Component in app directory in Next 13
Setup
// src/blitz-server.ts
export const { ... , useAuthenticatedBlitzContext} = setupBlitzServer({
...
})
In a RSC page or layout
import {getBlitzContext} from "src/blitz-server"
import getCurrentUser from "src/users/queries/getCurrentUser"
export default async function Home() {
const ctx = await getBlitzContext()
const user = await getCurrentUser(null, ctx)
return(
<>
...
</>
)
}
This hook is implemented as the replacement of the BlitzPage Security Auth Utilities provided for the pages directory to work with React Server Components in the Next 13 app
directory
It can be used in any asynchronous server component be it in page.ts
or in the layouts in layout.ts
useAuthenticatedBlitzContext({
redirectTo,
redirectAuthenticatedTo,
role,
}: {
redirectTo?: string | RouteUrlObject
redirectAuthenticatedTo?: string | RouteUrlObject | ((ctx: Ctx) => string | RouteUrlObject)
role?: string | string[]
}): Promise<void>
redirectTo
The URL
or Route
object passed to this parameter will be used to redirect
unauthenticated users (logged-out) and the users whose roles does not satisfy the required roles mentioned in the roles
parameter
role
This parameter takes a role (as string) or multipe roles to be used to authorize user access to a particular page or layout
redirectAuthenticatedTo
The URL
or Route
object passed to this parameter will be used to redirect
authenticated (logged-in) users.
Example Usage in React Server Component in app directory in Next 13
Setup
// src/blitz-server.ts
export const { ... , useAuthenticatedBlitzContext} = setupBlitzServer({
...
})
In a RSC Page or Layout
import {useAuthenticatedBlitzContext} from "src/blitz-server"
...
await useAuthenticatedBlitzContext({
redirectTo: "/auth/login",
role: ["admin"],
redirectAuthenticatedTo: "/dashboard",
})
The following method are to be used to invoke a resolver in a react server component
invoke
Let's say there is a requirement to query a resolver in the (root)/page.js
file to check the details of the current user
First import the invoke
function from the blitz-server
file.
Note we cannot directly import invoke
from @blitzjs/rpc
due to the necessity to run the required middleware in order to make it work effectively.
Setup
// src/blitz-server.ts
import {RpcServerPlugin} from "@blitzjs/rpc"
...
export const {... , invoke} = setupBlitzServer({
plugins: [
...
RpcServerPlugin({}),
]
...
})
In a RSC Page or Layout
import {invoke} from "src/blitz-server"
import getCurrentUser from "src/users/queries/getCurrentUser"
Now, we can directly invoke the resolver using the invoke function
const user = await invoke(getCurrentUser, null)