storybook: Relative URLs to assets no longer work in CSS now that CSS no longer gets inlined

Describe the bug I just upgraded to Storybook 4, and I think this issue is caused by that (it required a lot of other moving parts as well).

Basically, in my React component, I import './Widget.css';. Then in Widget.css, I reference a background image located in the same folder as such: background-image: url(orcid_16x16.png);.

With Storybook 3, this just worked even using build-storybook: the image URL was updated to static/media/orcid_16x16.2dddb203.png, and since the CSS was inline, this path was correct.

Now with Storybook 4, however, the URL is still updated to that value, but because it is now located in a CSS file that itself located in static/css, the browser is now trying to find the image at static/css/static/media/, and hence cannot find it.

To Reproduce Steps to reproduce the behavior:

  1. Visit my built Storybook v3
  2. Notice that there is a green icon to the left-hand side of Alice Doe
  3. Now visit that same page in Storybook 4
  4. Notice that the image is missing

Expected behavior The image to also be present in Storybook 4 - presumably by making sure that URL imports are rewritten to be relative to the CSS file they are in.

Screenshots

In Storybook 3: image

In Storybook 4: image

System:

  • OS: Ubuntu Linux 18.04
  • Device: Dell XPS 13 9360
  • Browser: Firefox
  • Framework: React
  • Addons: [if relevant]
  • Version: 4.0.0

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 39 (18 by maintainers)

Most upvoted comments

I am getting exactly same issue with “@storybook/react”: “^5.3.7”,

css is trying to look for a font file in static/css/static/media/myfont.woff2

but the font is at following url: static/media/myfont.woff2

in my project - i was able to remedy this by adding the "homepage": "." to my package json -> https://create-react-app.dev/docs/deployment/#serving-the-same-build-from-different-paths

not sure if this helps anyone^

seems like the relevant lines in CRA look something like this (https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js):

  // common function to get style loaders
  const getStyleLoaders = (cssOptions, preProcessor) => {
    const loaders = [
      isEnvDevelopment && require.resolve('style-loader'),
      isEnvProduction && {
        loader: MiniCssExtractPlugin.loader,
        // css is located in `static/css`, use '../../' to locate index.html folder
        // in production `paths.publicUrlOrPath` can be a relative path
        options: paths.publicUrlOrPath.startsWith('.')
          ? { publicPath: '../../' }
          : {},
      },

and public path is set below:

      // webpack uses `publicPath` to determine where the app is being served from.
      // It requires a trailing slash, or the file assets will get an incorrect path.
      // We inferred the "public path" (such as / or /my-project) from homepage.
      publicPath: paths.publicUrlOrPath,

This is still happening on non-CRA apps.

In CSS.

// foo.module.scss
background: url('./logo.svg') 30px center no-repeat $white;

After Storybook.

static/media/logo.f6b1d730.svg

For anybody still having this issue down the road on a non-CRA app, please reference this SO thread

The key of this is in specifying { url: false } in the CSS Module rule of your webpack config. Here is the specific configuration I used for my CSS Module rule:

config.module.rules.push({
    test: /\.module\.css$/,
    use: [
        require.resolve('style-loader'),
        {
            loader: require.resolve('css-loader'),
            options: {
                modules: {...}, // project-specific module naming conventions, config, etc.
                url: false,
                importLoaders: 1,
            },
        },
    ],
}) 

Hope this can save some time for anybody else!

Same for the version 5.3.13

Hello. Successfully solved it by adding this to my .storybook/main.js

const path = require('path');

const publicPath = process.env.DEV ? "http://localhost:9009/" :"https://your-web-address.com/"

module.exports = {
	stories: ['../src/**/*.stories.js'],
	addons: [
		'@storybook/preset-create-react-app',
		'@storybook/addon-actions',
		'@storybook/addon-links',
		'@storybook/addon-knobs'],

	webpackFinal: async (config, { configType }) => {
	
		config.output.publicPath=publicPath

		return config;
	},
};


Hopefully it could help you.

Just upgraded to 4.0.4, and it works flawlessly. Thanks!