Open mcavaliere opened 2 years ago
I really like this method of assigning layout functions to the page modules as a property. This worked pretty well in a JS app but it got kind of tricky for TS apps. Blitz.js does something pretty similar for their pages and layouts so I looked at their source to figure out how to make this technique work in a Next.js app with TypeScript. You can write a types/index.ts
file and add:
import type { AppProps as NextAppProps } from 'next/app'
import type {
NextComponentType as DefaultNextComponentType,
NextPage as DefaultNextPage,
NextPageContext,
} from 'next'
export type GetLayoutFunction = (component: JSX.Element) => JSX.Element
export declare type NextComponentType<
C = NextPageContext,
IP = Record<string, unknown>,
P = Record<string, unknown>,
> = DefaultNextComponentType<C, IP, P>
export interface AppProps<P = Record<string, unknown>> extends NextAppProps<P> {
Component: NextComponentType<NextPageContext, any, P> & {
getLayout?: GetLayoutFunction
}
}
export declare type NextPage<P = Record<string, unknown>, IP = P> = DefaultNextPage<P, IP> & {
getLayout?: GetLayoutFunction
}
In _app.tsx
import the AppProps
type from the custom type definitions:
// Old type import
// import type { AppProps } from 'next/app'
// New type import
import type { AppProps } from 'types'
function MyApp({ Component, pageProps }: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
return getLayout(<Component {...pageProps} />)
}
export default MyApp
Then in a page files use the custom NextPage
definition:
// Old type import
// import type { NextPage } from 'next'
// New type import
import type { NextPage } from '../types'
const HomePage: NextPage = () => {
...
Then the type errors are gone 😅
To keep page transitions snappy, we should be using page layout components and static
getLayout
methods. This allows us to have centralized header/footer content that doesn't get re-rendered when going from one page to another.To see them in action, navigate back and forth from this article index page and any of the articles.
This article I wrote, Next.js Page Layouts and Dynamic Content shows how to inject dynamic page-specific content into the layouts and still have them equally snappy.