先日 Next.js(App Router) プロジェクトで Storybook を利用している際に、上記のinvariant expected app router to be mounted
というエラーに直面したので、解決方法を記載しておきます。
エラーの原因
Story で next/navigation を利用したコンポーネントをインポートしようとすると、エラーが発生するようです。この問題を解決するためには、appDirectory パラメータを true に設定する必要があります。
エラー発生当時のコンポーネントと Story の状態
import { ExampleComponent } from "./ExampleComponent";
import { Meta, StoryObj } from '@storybook/react'
const meta = {
title: 'ExampleComponent',
component: ExampleComponent,
} satisfies Meta<typeof ExampleComponent>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
render: () => (
<ExampleComponent />
)
}
import { useRouter } from 'next/navigation'
import { useForm } from 'react-hook-form'
export const ExampleComponent = () => {
const router = useRouter()
const form = useForm()
const onSubmit = (data) => {
router.push('/some-route')
}
return (
<form onSubmit={form.handleSubmit(onSubmit)}>
{/* フォーム内容 */}
</form>
)
}
解決方法
上記でも説明しましたが、 nextjs.appDirectory
パラメータを true
に設定することで、このエラーを解決できます。
import { ExampleComponent } from "./ExampleComponent";
import { Meta, StoryObj } from '@storybook/react'
const meta = {
title: 'ExampleComponent',
component: ExampleComponent,
parameters: {
nextjs: {
appDirectory: true,
},
},
} satisfies Meta<typeof ExampleComponent>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
render: () => (
<ExampleComponent />
)
}
また、プロジェクト全体で appDirectory を設定することもできます。preview.ts
ファイルで以下のように設定を行います。
import { Preview } from '@storybook/react';
const preview: Preview = {
parameters: {
nextjs: {
appDirectory: true,
},
},
};
export default preview;
まとめ
Next.js の App Router を使用するコンポーネントを Storybook に追加する際には、特に next/navigation
の useRouter
や usePathname
を使用している場合、nextjs.appDirectory
パラメータを設定することを忘れないようにしましょう。これにより、コンポーネントが正しくレンダリングされ、invariant expected app router to be mounted
エラーを回避できます。
この記事が、同じ問題に直面している他の開発者の助けになれば幸いです。