Back to Storybook

Nextjs Navigation Mock

docs/_snippets/nextjs-navigation-mock.md

10.3.64.3 KB
Original Source
js
import { expect } from 'storybook/test';

// Replace your-framework with nextjs or nextjs-vite
import { redirect, getRouter } from '@storybook/your-framework/navigation';

import MyForm from './my-form';

export default {
  component: MyForm,
  parameters: {
    nextjs: {
      // ๐Ÿ‘‡ As in the Next.js application, next/navigation only works using App Router
      appDirectory: true,
    },
  },
};

export const Unauthenticated = {
  async play() {
    // ๐Ÿ‘‡ Assert that your component called redirect()
    await expect(redirect).toHaveBeenCalledWith('/login', 'replace');
  },
};

export const GoBack = {
  async play({ canvas, userEvent }) {
    const backBtn = await canvas.findByText('Go back');

    await userEvent.click(backBtn);
    // ๐Ÿ‘‡ Assert that your component called back()
    await expect(getRouter().back).toHaveBeenCalled();
  },
};
ts
// Replace your-framework with nextjs or nextjs-vite
import type { Meta, StoryObj } from '@storybook/your-framework';

import { expect } from 'storybook/test';

// ๐Ÿ‘‡ Must include the `.mock` portion of filename to have mocks typed correctly
import { redirect, getRouter } from '@storybook/your-framework/navigation.mock';

import MyForm from './my-form';

const meta = {
  component: MyForm,
  parameters: {
    nextjs: {
      // ๐Ÿ‘‡ As in the Next.js application, next/navigation only works using App Router
      appDirectory: true,
    },
  },
} satisfies Meta<typeof MyForm>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Unauthenticated: Story = {
  async play() {
    // ๐Ÿ‘‡ Assert that your component called redirect()
    await expect(redirect).toHaveBeenCalledWith('/login', 'replace');
  },
};

export const GoBack: Story = {
  async play({ canvas, userEvent }) {
    const backBtn = await canvas.findByText('Go back');

    await userEvent.click(backBtn);
    // ๐Ÿ‘‡ Assert that your component called back()
    await expect(getRouter().back).toHaveBeenCalled();
  },
};
ts
import { expect } from 'storybook/test';

/*
 * Replace your-framework with nextjs or nextjs-vite
 * ๐Ÿ‘‡ Must include the `.mock` portion of filename to have mocks typed correctly
 */
import { redirect, getRouter } from '@storybook/your-framework/navigation.mock';

import preview from '../.storybook/preview';

import MyForm from './my-form';

const meta = preview.meta({
  component: MyForm,
  parameters: {
    nextjs: {
      // ๐Ÿ‘‡ As in the Next.js application, next/navigation only works using App Router
      appDirectory: true,
    },
  },
});

export const Unauthenticated = meta.story({
  async play() {
    // ๐Ÿ‘‡ Assert that your component called redirect()
    await expect(redirect).toHaveBeenCalledWith('/login', 'replace');
  },
});

export const GoBack = meta.story({
  async play({ canvas, userEvent }) {
    const backBtn = await canvas.findByText('Go back');

    await userEvent.click(backBtn);
    // ๐Ÿ‘‡ Assert that your component called back()
    await expect(getRouter().back).toHaveBeenCalled();
  },
});
<!-- JS snippets still needed while providing both CSF 3 & Next -->
js
import { expect } from 'storybook/test';

// Replace your-framework with nextjs or nextjs-vite
import { redirect, getRouter } from '@storybook/your-framework/navigation.mock';

import preview from '../.storybook/preview';

import MyForm from './my-form';

const meta = preview.meta({
  component: MyForm,
  parameters: {
    nextjs: {
      // ๐Ÿ‘‡ As in the Next.js application, next/navigation only works using App Router
      appDirectory: true,
    },
  },
});

export const Unauthenticated = meta.story({
  async play() {
    // ๐Ÿ‘‡ Assert that your component called redirect()
    await expect(redirect).toHaveBeenCalledWith('/login', 'replace');
  },
});

export const GoBack = meta.story({
  async play({ canvas, userEvent }) {
    const backBtn = await canvas.findByText('Go back');

    await userEvent.click(backBtn);
    // ๐Ÿ‘‡ Assert that your component called back()
    await expect(getRouter().back).toHaveBeenCalled();
  },
});