next.js
next.js copied to clipboard
Next image optimization not working with storybook, even after applying the storybook nextjs addon
Verify canary release
- [X] I verified that the issue exists in Next.js canary release
Provide environment information
Operating System:
Platform: win32
Arch: x64
Version: Windows 10 Home
Binaries:
Node: 16.14.0
npm: 8.3.1
Yarn: 1.22.15
pnpm: N/A
Relevant packages:
next: 12.1.6
react: 18.1.0
react-dom: 18.1.0
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
After applying all solution in the following tread issue#18393, I still have the following error:
failed to parse src "static/media/public/sofia.png" on `next/image`, if using relative image it must start with a leading slash "/" or be an absolute URL (http:// or https://)
I also used the nextjs storybook addon
I am sure it is about next/image optimization because as soon as I add unoptimized
flag to nextjs Image
component it works perfectly.
Expected Behavior
Nextjs Image
should work with storybook after using nextjs storybook addon
Or after adding the following custom solution
To Reproduce
Create a new Nextjs yarn create next-app --typescript
Add webpack5 resolver to package.json
"resolutions": {
"webpack": "^5"
},
Install webpack resolution yarn
Add storybook to Nextjs npx -y sb init --builder webpack5
Add Storybook Nextjs addon yarn add --dev storybook-addon-next
My tsconfig.json
:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@public/*": ["public/*"],
},
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
My storybook main.js
:
const path = require('path');
module.exports = {
stories: [
"../components/**/*.stories.mdx",
"../components/**/*.stories.@(js|jsx|ts|tsx)",
],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"storybook-addon-next",
],
framework: "@storybook/react",
core: {
builder: "@storybook/builder-webpack5",
},
webpackFinal: (config) => {
config.resolve.alias = {
...config.resolve?.alias,
"@public": path.resolve(__dirname, "../public"),
};
return config;
},
};
My storybook preview.js
:
import "../styles/globals.css";
import * as NextImage from 'next/image'
const OriginalNextImage = NextImage.default
Object.defineProperty(NextImage, 'default', {
configurable: true,
value: (props) => (
<OriginalNextImage {...props} unoptimized loader={({ src }) => src} />
),
})
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
My file structure:
components/
/Dummy
index.tsx
Dummy.stories.tsx
pages/
tailwind.config.js
next.config.js
postcss.config.js
tsconfig.json
next-env.d.ts
public/
yarn.lock
node_modules/
README.md
yarn-error.log
package.json
styles/
All my components are in the components
folder, images are directly placed in the public
folder.
Here is an example of a Dummy component:
// index.js
import Sofia from "@public/sofia.png";
import Image from "next/image";
export function Dummy() {
console.log(process.env.ENV)
return (
<div className="bg-slate-400 text-white w-28">
dummy
<Image src={Sofia} layout="responsive" />
</div>
);
}
And associated story:
// Dummy.stories.tsx
import { ComponentStory, ComponentMeta } from "@storybook/react";
import { Dummy } from ".";
export default {
title: "Example/Dummy",
component: Dummy,
} as ComponentMeta<typeof Dummy>;
const Template: ComponentStory<typeof Dummy> = (args) => <Dummy />;
export const Primary = Template.bind({});
@encetroc I ran into this when I upgraded to 12.1.5+
There's an updated workaround for preview.js
in this comment here: https://github.com/vercel/next.js/issues/36417#issuecomment-1117360509
The workaround of injecting the unoptimised
prop into the next/image
was working for us with external images until we upgraded Next.js and Storybook. The following code addition found in this discussion solved it once again for Next.js 12.1.6 and Storybook 6.5.6:
import NextImage from 'next/image';
NextImage.propTypes = {
unoptimized: null,
};
NextImage.defaultProps = {
unoptimized: true,
};
I was having issues with images in Storybook returning a 404 while using a custom loader such as Imgix. You can solve this by either passing in the full URL to the image in your stories or just adding the base path inside preview.js
:
import * as NextImage from 'next/image';
const basePath = '<your base path here>';
const OriginalNextImage = NextImage.default;
Object.defineProperty(NextImage, 'default', {
configurable: true,
value: ({ src, ...props }) => (
<OriginalNextImage
src={`${basePath}${src}`}
{...props}
unoptimized
/>
),
});
Object.defineProperty(NextImage, '__esModule', {
configurable: true,
value: true,
});
I was having issues with images in Storybook returning a 404 while using a custom loader such as Imgix. You can solve this by either passing in the full URL to the image in your stories or just adding the base path inside
preview.js
:import * as NextImage from 'next/image'; const basePath = '<your base path here>'; const OriginalNextImage = NextImage.default; Object.defineProperty(NextImage, 'default', { configurable: true, value: ({ src, ...props }) => ( <OriginalNextImage src={`${basePath}${src}`} {...props} unoptimized /> ), }); Object.defineProperty(NextImage, '__esModule', { configurable: true, value: true, });
Update
Now getting an error with this config on Next.js 12.2.4
: Uncaught TypeError: Cannot redefine property: __esModule
Removing the Object.defineProperty(NextImage, '__esModule'...
fixes it.
Please verify that your issue can be recreated with next@canary
.
Why was this issue marked with the please verify canary
label?
We noticed the provided reproduction was using an older version of Next.js, instead of canary
.
The canary version of Next.js ships daily and includes all features and fixes that have not been released to the stable version yet. You can think of canary as a public beta. Some issues may already be fixed in the canary version, so please verify that your issue reproduces by running npm install next@canary
and test it in your project, using your reproduction steps.
If the issue does not reproduce with the canary
version, then it has already been fixed and this issue can be closed.
How can I quickly verify if my issue has been fixed in canary
?
The safest way is to install next@canary
in your project and test it, but you can also search through closed Next.js issues for duplicates or check the Next.js releases. You can also use the GitHub template (preferred), or the CodeSandbox or StackBlitz templates to create a reproduction with canary
from scratch.
My issue has been open for a long time, why do I need to verify canary
now?
Next.js does not backport bug fixes to older versions of Next.js. Instead, we are trying to introduce only a minimal amount of breaking changes between major releases.
What happens if I don't verify against the canary version of Next.js?
An issue with the please verify canary
that receives no meaningful activity (e.g. new comments that acknowledge verification against canary
) will be automatically closed and locked after 30 days.
If your issue has not been resolved in that time and it has been closed/locked, please open a new issue, with the required reproduction, using next@canary
.
I did not open this issue, but it is relevant to me, what can I do to help?
Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps. Furthermore, you can upvote the issue using the :+1: reaction on the topmost comment (please do not comment "I have the same issue" without repro steps). Then, we can sort issues by votes to prioritize.
I think my reproduction is good enough, why aren't you looking into it quicker?
We look into every Next.js issue and constantly monitor open issues for new comments.
However, sometimes we might miss one or two due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.
Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.
Useful Resources
This issue has been automatically closed because it wasn't verified against next@canary. If you think it was closed by accident, please leave a comment. If you are running into a similar issue, please open a new issue with a reproduction. Thank you.
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.