Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock Next.js Image component in Storybook?

Next.js introduced a new Image component in v10 that's supposed to be a drop in replacement for the <img> tag.

I'm having an error when trying to view components that import next/image into Storybook:

TypeError: imageData is undefined

I have been trying to override the image object in preview.js (a technique I use for next/router, as documented here) but I get the same error:

// .storybook/preview.js

import Image from 'next/image';

Image = ({ src }) => <img src={src} />;

Any idea how I could override the behaviour of the next/image package in Storybook?

like image 885
drskullster Avatar asked Oct 31 '20 14:10

drskullster


2 Answers

I finally managed to make it work.

First we need to define an env variable with the default settings to get rid of the error. We can do this by plugging into webpack in .storybook/main.js:

// .storybook/main.js
var webpack = require('webpack');

module.exports = {
  ...
  webpackFinal: (config) => {
    config.plugins.push(new webpack.DefinePlugin({
      'process.env.__NEXT_IMAGE_OPTS': JSON.stringify({
        deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
        imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
        domains: [],
        path: '/',
        loader: 'default',
      }),
    }));
    return config;
  },
};

Now we can override the default export from next/image package with a functional component that returns a simple <img/> tag.

// .storybook/preview.js

import * as nextImage from 'next/image';

Object.defineProperty(nextImage, 'default', {
  configurable: true,
  value: (props) => {
    return <img {...props} />;
  },
});

I'm using the defineProperty static method for this (link to MDN article) since I can't just assign a new value to Image.default.

like image 129
drskullster Avatar answered Sep 16 '22 16:09

drskullster


As an addition to the accepted answer:

add var webpack = require('webpack');inside main.js

like image 44
Arseny Bobrov Avatar answered Sep 19 '22 16:09

Arseny Bobrov