Recently, I was confronted with the problem that an image doesn't appear in the image component in storybook
.
I searched for a solution and I found the issue.
Even though there is already such a solution, it was a little hard to find it. This is why I am writing this post. Actually, there are other ways to solve the problem with some code but I didn't want to write more code in my project.
First, let me show you the problem. I set up a project with a command npx create-next-app
and made a component.
import Image from "next/image";
import styled from "@emotion/styled";
export const IconButton = ({
src,
children,
width = 120,
onClick,
iconSize = 24,
}) => {
return (
<Button onClick={onClick} width={width}>
<Image
src={src}
width={iconSize}
height={iconSize}
alt="icon of the button"
/>
<Text>{children}</Text>
</Button>
);
};
const Button = styled.div`
box-sizing: border-box;
width: ${({ width }) => width}px;
border-radius: 8px;
height: 40px;
padding: 8px;
display: flex;
alignitems: center;
column-gap: 6px;
background-color: #3498db;
color: white;
position: relative;
&:hover {
cursor: pointer;
opacity: 0.7;
}
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;
`;
const Text = styled.div`
position: absolute;
top: 0;
bottom: 10%;
left: 8px;
right: 0;
display: flex;
align-items: center;
justify-content: center;
`;
I downloaded an image(from here) and put it to public directory.
Here is a code of the index page and the result.
Please, ignore the design
import { IconButton } from "../components/IconButton";
export default function Home() {
return (
<div>
<h3>Example</h3>
<IconButton src="/icons/home.png">Button</IconButton>
</div>
);
}
The image appears well.
Let's look at this in storybook. I added a line in main.js for serving static files.
.storybook/main.js
module.exports = {
stories: ["../components/**/*.stories.(js|jsx|ts|tsx)"],
addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
framework: "@storybook/react",
staticDirs: ["../public"], // Here
};
IconButton.stories.js
import { IconButton } from ".";
// eslint-disable-next-line import/no-anonymous-default-export
export default {
title: "components/IconButton",
component: IconButton,
args: {
width: 120,
iconSize: 24,
children: "Button",
},
};
const Template = (args) => <IconButton {...args} />;
export const Home = Template.bind({});
Home.args = {
src: "/icons/home.png",
};
The image doesn't appear, right?
The src of the image points /_next/image
.
Now, install the package storybook-addon-next
.
npm install -D storybook-addon-next
Then, add the addon
to main.js
.
module.exports = {
stories: ["../components/**/*.stories.(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"storybook-addon-next", // Here
],
framework: "@storybook/react",
staticDirs: ["../public"],
};
Restart the storybook.
.....?!
An error occurs. I've encountered it while writing this post, meanwhile I haven't seen any errors in my project.
Log
info @storybook/react v6.4.18
info
info => Loading presets
info => Serving static files from ./.\public at /
(node:14304) DeprecationWarning: You have specified an invalid glob, we've attempted to fix it, please ensure that the glob you specify is valid. See: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#correct-globs-in-mainjs
(Use `node --trace-deprecation ...` to show where the warning was created)
info => Using implicit CSS loaders
info => Using default Webpack4 setup
ERR! WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
ERR! - configuration.module.rules[12].type should be one of these:
ERR! "javascript/auto" | "javascript/dynamic" | "javascript/esm" | "json" | "webassembly/experimental"
ERR! -> Module type to use for the module
ERR! at webpack (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\webpack\lib\webpack.js:31:9)
ERR! at Object.start (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\@storybook\builder-webpack4\dist\cjs\index.js:92:18)
ERR! at async Promise.all (index 0)
ERR! at async storybookDevServer (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\@storybook\core-server\dist\cjs\dev-server.js:126:28)
ERR! at async buildDevStandalone (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\@storybook\core-server\dist\cjs\build-dev.js:115:31)
ERR! at async buildDev (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\@storybook\core-server\dist\cjs\build-dev.js:161:5)
ERR! WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
ERR! - configuration.module.rules[12].type should be one of these:
ERR! "javascript/auto" | "javascript/dynamic" | "javascript/esm" | "json" | "webassembly/experimental"
ERR! -> Module type to use for the module
ERR! at webpack (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\webpack\lib\webpack.js:31:9)
ERR! at Object.start (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\@storybook\builder-webpack4\dist\cjs\index.js:92:18)
ERR! at async Promise.all (index 0)
ERR! at async storybookDevServer (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\@storybook\core-server\dist\cjs\dev-server.js:126:28)
ERR! at async buildDevStandalone (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\@storybook\core-server\dist\cjs\build-dev.js:115:31)
ERR! at async buildDev (C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test\node_modules\@storybook\core-server\dist\cjs\build-dev.js:161:5)
WARN Broken build, fix the error above.
WARN You may need to refresh the browser.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! next-storybook-image-test@ storybook: `start-storybook -p 6006`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the next-storybook-image-test@ storybook script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\hskco\AppData\Roaming\npm-cache\_logs\2022-02-06T07_30_05_523Z-debug.log
PS C:\Users\hskco\OneDrive\바탕 화면\dev\next-storybook-image-test>
The installed package is storybook-addon-next^1.4.1
. I used v1.4.0
in my project. So, I'll reinstall the package with npm install storybook-addon-next@1.4.0
.
Finally it works! I think there was something wrong with the version v1.4.1
.
I hope this post will be helpful. Good coding!
+Plus
I've reported the storybook-addon-next issue in github and I got the answer from the author.
It was the problem of the webpack
version.
There is the guide for upgrading the builder from webpack4
to webpack5
.
After upgrading it, storybook-addon-next@1.4.1
works.
If you haven't started your project yet, I'd recommend you to initialize the storybook with npx sb init --builder webpack5
.
Top comments (2)
Thanks for sharing this. I was missing the storybook nextjs addon.
Good to hear it helped :)