storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.95k stars 9.21k forks source link

[Bug]: Next.js 14 localFont + vanilla extract error #28723

Open brgndyy opened 1 month ago

brgndyy commented 1 month ago

Describe the bug

Summary

Hello, I am currently using Next.js14 version.

I applied the localFont application method as written in the official document, but the error as shown in the picture continues to occur.

Is the path wrong? Even though I followed the same path as the official document, an error occurred and I don't know where the error is.

Currently, the font is applied normally within the application, but the error occurs only in storybook.

스크린샷 2024-07-26 오전 7 22 49

src/components/fonts/font.ts

import localFont from 'next/font/local';

export const myFont = localFont({
  src: './BMHANNAAir_ttf.ttf',
  display: 'swap',
});
스크린샷 2024-07-26 오전 7 25 22 스크린샷 2024-07-26 오전 7 27 46

Additional information

- main.ts

import type { StorybookConfig } from '@storybook/nextjs';
import type { PresetValue } from '@storybook/types';
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import path from 'path';

const config: StorybookConfig = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-onboarding',
    '@storybook/addon-interactions',
    '@chromatic-com/storybook',
    '@storybook/addon-styling-webpack',
  ],
  framework: {
    name: '@storybook/nextjs',
    options: {},
  },

  docs: {},
  typescript: {
    reactDocgen: 'react-docgen-typescript',
  } as PresetValue<Partial<import('@storybook/types').TypescriptOptions> | undefined>,

// This is the path written in the official document.
  staticDirs: [
    {
      from: '../src/components/fonts',
      to: 'src/components/fonts',
    },
  ],

  webpackFinal(config, options) {
    // Add Vanilla-Extract and MiniCssExtract Plugins
    config.plugins?.push(new VanillaExtractPlugin(), new MiniCssExtractPlugin());

    // Exclude vanilla extract files from regular css processing
    config.module?.rules?.forEach((rule) => {
      if (
        rule &&
        typeof rule !== 'string' &&
        rule.test instanceof RegExp &&
        rule.test.test('test.css')
      ) {
        rule.exclude = /\.vanilla\.css$/i;
      }
    });

    config.module?.rules?.push({
      test: /\.vanilla\.css$/i, // Targets only CSS files generated by vanilla-extract
      use: [
        MiniCssExtractPlugin.loader,
        {
          loader: require.resolve('css-loader'),
          options: {
            url: false, // Required as image imports should be handled via JS/TS import statements
          },
        },
      ],
    });

    config.module?.rules?.push({
      test: /\.(ttf|woff|woff2|eot|otf)$/,
      use: [
        {
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'fonts/',
          },
        },
      ],
    });

    config.resolve = config.resolve || {};
    config.resolve.alias = config.resolve.alias || {};

    config.resolve.alias['@'] = path.resolve(__dirname, '../src');

    return config;
  },
};

export default config;

- preview.tsx

import type { Preview } from '@storybook/react';
import { fn } from '@storybook/test';
import React from 'react';
import { myFont } from '../src/components/fonts/font';

const preview: Preview = {
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
  },
  globalTypes: {
    action: fn,
  },
};

export const decorators = [
  (Story) => (
    <div className={myFont.className}>
      <Story />
    </div>
  ),
];

export default preview;
스크린샷 2024-07-26 오전 7 29 38 스크린샷 2024-07-26 오전 7 30 10

Create a reproduction

No response

Reproduction link

https://github.com/brgndyy/BEING_JAZZER/blob/main/front/.storybook/main.ts

Reproduction steps

No response

System

{
  "devDependencies": {
    "@chromatic-com/storybook": "^1.5.0",
    "@storybook/addon-essentials": "^8.1.9",
    "@storybook/addon-interactions": "^8.1.9",
    "@storybook/addon-links": "^8.1.9",
    "@storybook/addon-mdx-gfm": "^8.1.9",
    "@storybook/addon-onboarding": "^8.1.9",
    "@storybook/blocks": "^8.1.9",
    "@storybook/nextjs": "^8.1.9",
    "@storybook/react": "^8.1.9",
    "@storybook/test": "^8.1.9",
    "storybook": "^8.1.9"
  },
}

Additional context

No response

greptile-apps[bot] commented 1 month ago

Disclaimer This information might be inaccurate, due to it being generated automatically To resolve the issue with local fonts in Storybook for Next.js 14, follow these steps:

  1. Update main.ts:

    • Ensure the staticDirs path is correct:
      staticDirs: [
      { from: '../src/components/fonts', to: '/fonts' },
      ],
  2. Configure Webpack:

    • Add a rule for handling font files in webpackFinal:
      config.module?.rules?.push({
      test: /\.(ttf|woff|woff2|eot|otf)$/,
      use: [
      {
       loader: 'file-loader',
       options: {
         name: '[name].[ext]',
         outputPath: 'fonts/',
       },
      },
      ],
      });
  3. Update Font Import Path:

    • Ensure the font path in font.ts is correct:
      export const myFont = localFont({
      src: '/fonts/BMHANNAAir_ttf.ttf',
      display: 'swap',
      });
  4. Use Font in Storybook:

    • Wrap your Storybook decorators with the font class:
      export const decorators = [
      (Story) => (
      <div className={myFont.className}>
       <Story />
      </div>
      ),
      ];

These steps should resolve the font loading issue in Storybook.

References

/code/frameworks/nextjs/src/font/webpack/loader/local /code/frameworks/nextjs/template/stories_nextjs-default-js/Font.jsx /code/frameworks/nextjs/src/font/webpack /code/frameworks/nextjs/src/font/webpack/loader /code/frameworks/nextjs/template/stories_nextjs-default-js /code/frameworks/nextjs/src/font/webpack/configureNextFont.ts /test-storybooks/portable-stories-kitchen-sink/nextjs/stories/fonts /code/core/src/server-errors.ts /code/frameworks/nextjs/src/font/babel/index.test.ts /code/frameworks/nextjs/src/font/webpack/loader/utils /code/core/src/preview-errors.ts /.github/DISCUSSION_TEMPLATE/help.yml /docs/configure/webpack.mdx /test-storybooks/portable-stories-kitchen-sink/nextjs/.storybook /test-storybooks/portable-stories-kitchen-sink/nextjs/stories /test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Font.tsx /code/frameworks/nextjs/src/font/webpack/loader/storybook-nextjs-font-loader.ts /.github/comments/invalid-link.md /code/frameworks/nextjs/template/stories_nextjs-default-js/fonts /code/lib/cli/src/automigrate/fixes/prompt-remove-react.ts /test-storybooks/portable-stories-kitchen-sink/react/.storybook /code/lib/cli/src/link.ts /docs/_snippets/web-components-webpack5-add-framework.md /code/addons/onboarding/package.json /code/frameworks/nextjs/template/cli/ts-4-9

#### About Greptile This response provides a starting point for your research, not a precise solution. Help us improve! Please leave a 👍 if this is helpful and 👎 if it is irrelevant. [Ask Greptile](https://app.greptile.com/chat/github/storybookjs/storybook/next) · [Edit Issue Bot Settings](https://app.greptile.com/apps/github)