Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting publicPath almost works. #3172

Closed
manuphatak opened this issue Mar 8, 2018 · 25 comments
Closed

Setting publicPath almost works. #3172

manuphatak opened this issue Mar 8, 2018 · 25 comments

Comments

@manuphatak
Copy link

manuphatak commented Mar 8, 2018

Issue details

Overriding config.output.publicpath does not work.

Here's the scenario:

As a developer, I want QA and Design teams to be able to review storybook on review apps. I want to be able to publish storybook as a path on my main app: for example pr-2200.example.com/storybook/.

If I set public path, it almost works:

// .storybook/webpack.config.js
module.exports = (storybookBaseConfig, configType) => {
  if (configType === 'PRODUCTION') {
    storybookBaseConfig.output.publicPath = '/storybook/'
  }

  return storybookBaseConfig
}

There's one line, that seems to ignore webpack's publicPath:
https://github.com/storybooks/storybook/blob/abd4f0ef697c0b62ee724fd88e3c245efd4bd912/lib/core/src/client/manager/provider.js#L34

As a hack, I can fix this, by creating a redirect on my server.

For example, on rails, I can do:

  # config/routes.rb
  get 'iframe.html', to: redirect(path: '/storybook/iframe.html')

(edited this snippet): redirect('/storybook/iframe.html') -> redirect(path: '/storybook/iframe.html'). This subtle change forwards url params with the redirect.

And everything works!

It would better if everything worked without creating a redirect on my server.

Please specify which version of Storybook and optionally any affected addons that you're running

  • storybook/react "3.2.x"

Affected platforms

  • React version of the app.
@Hypnosphi
Copy link
Member

Hypnosphi commented Mar 18, 2018

There's some related discussion in #3010 (comment)

@Hypnosphi
Copy link
Member

Hypnosphi commented Mar 18, 2018

In case of static build, you can just serve storybook-static directory to /storybook/ path and it should work because of https://github.com/storybooks/storybook/blob/master/app/react/src/server/config/webpack.config.prod.js#L24-L29

@stale
Copy link

stale bot commented Apr 8, 2018

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label Apr 8, 2018
@xiaolin
Copy link

xiaolin commented Apr 24, 2018

@bionikspoon Did you ever resolve your issue besides using a redirect? I'm also running into the same issue setting up the static content to load in a django application.

@stale stale bot removed the inactive label Apr 24, 2018
@manuphatak
Copy link
Author

@xiaolin no, still using the redirect.

@Hypnosphi
Copy link
Member

What happens if you don't override publicPath from our default config?

@stale
Copy link

stale bot commented May 25, 2018

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label May 25, 2018
@chardskarth
Copy link

chardskarth commented Jun 1, 2018

I really can't change webpack's output.publicPath and output.path even after using full control and this

If this is really impossible at the moment, I wonder if there's a workaround?

-- edited
Nope, I was wrong. output.publicPath was taking effect. It was output.path that wasn't working. But then --output-dir should be used to change it.

@stale stale bot removed the inactive label Jun 1, 2018
@Hypnosphi
Copy link
Member

Hypnosphi commented Jun 8, 2018

What do you need that for, @chardskarth ?

@chardskarth
Copy link

Well.

Intuitively, I thought to be able to control webpack’s custom output path, I’d simply have to edit ‘output.path’. But then **there’s no other way to control the output directory but to use the ‘—output-dir’ option.

And what do I need this for? To control storybook-build’s path.

@Hypnosphi
Copy link
Member

to use the ‘—output-dir’ option

So what's wrong with this?

@chardskarth
Copy link

It may be just me. But I find this not intuitive.

@marco-silva0000
Copy link

@xiaolin I have just made the redirect solution in django. with the following view and url

from django.views.generic.base import TemplateView
class IframeView(TemplateView):
    template_name = 'iframe.html'

@chardskarth were you able to make this work without the redirect? can you provide an example?
If this is the case, it should be included on the documentation.

@chardskarth
Copy link

Just like what you mentioned to @xiaolin, I made the solution directly in java spring.

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

   @Override
   public void addViewControllers(ViewControllerRegistry registry) {
       registry.addViewController("/storybook/**")
            .setViewName("forward:/storybook-build/index.html");
       registry.addViewController("iframe.html")
            .setViewName("forward:/storybook-build/iframe.html");
   }
}

@stale
Copy link

stale bot commented Aug 8, 2018

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label Aug 8, 2018
@stale
Copy link

stale bot commented Sep 7, 2018

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

@stale stale bot closed this as completed Sep 7, 2018
@kimamula
Copy link

@Hypnosphi

In case of static build, you can just serve storybook-static directory to /storybook/ path and it should work because of https://github.com/storybooks/storybook/blob/master/app/react/src/server/config/webpack.config.prod.js#L24-L29

If you visit /storybook/index.html, then it's OK.
However, if you visit /storybook, browser tries to fetch JS files under /static (not /storybook/static) which do not exist in this case.

@Hypnosphi
Copy link
Member

OK, you need a redirect then

@alexlafroscia
Copy link

I'm running into a similar issue as @kimamula, but in my case I'm trying to include the middleware for the server in an existing Express app, mounted at /storybook

If I make the request to /storybook I get an error about loading from /static but if I go to /storybook/index.html then the assets load correctly.

@signal-intrusion
Copy link

I feel like setting up server-side redirects is not the best solution for a client-side application. What if Storybook simply obeyed the consumer's setting for publicPath if it exists?

@joselcc
Copy link

joselcc commented Oct 15, 2020

static dir path mapping to a custom endpoint was added in this PR but it is available only in alpha version (6.1.0-alpha.23)
https://github.com/storybookjs/storybook/blob/next/lib/core/docs/standalone.md#for-static-mode

@yurist38
Copy link

yurist38 commented Mar 10, 2021

I've just figured this out finally! To fully set the path prefix you need to set publicPath in both webpackFinal and managerWebpack functions in the .storybook/main.js like this:

// .storybook/main.js
module.exports = {
  webpackFinal: async (config, { configType }) => {
    config.output.publicPath = '/my-prefix/';
    return config;
  },
  managerWebpack: async (config) => {
    config.output.publicPath = '/my-prefix/';
    return config;
  },
};

Also, I had to build Storybook with the preview-url parameter to make it find the iframe file:

build-storybook -- --preview-url=/my-prefix/iframe.html

For some reason, I have found nothing about it in official docs, had to google it a lot...

@chornos13
Copy link

chornos13 commented Jun 24, 2021

I've just figured this out finally! To fully set the path prefix you need to set publicPath in both webpackFinal and managerWebpack functions in the .storybook/main.js like this:

// .storybook/main.js
module.exports = {
  webpackFinal: async (config, { configType }) => {
    config.output.publicPath = '/my-prefix/';
    return config;
  },
  managerWebpack: async (config) => {
    config.output.publicPath = '/my-prefix/';
    return config;
  },
};

Also, I had to build Storybook with the preview-url parameter to make it find the iframe file:

build-storybook -- --preview-url=/my-prefix/iframe.html

For some reason, I have found nothing about it in official docs, had to google it a lot...

Hey, thank you that's giving me hope about custom publicPath

In my case with Storybook version 6.2.9 I just need managerWebpack configuration and giving some extra config because --preview-url doesn't seem to works

// .storybook/main.js
module.exports = {
  managerWebpack: async (config) => {
    configHtmlWebPackPlugin = config.plugins.find(plugin => plugin.constructor.name === 'HtmlWebpackPlugin')
    configHtmlWebPackPlugin.options.publicPath = '/assets/storybook/'
    config.output.publicPath = '/assets/storybook/'
    const oriTemplateParameters = configHtmlWebPackPlugin.options.templateParameters
    configHtmlWebPackPlugin.options.templateParameters = (compilation, files, options) => {
      oriReturn = oriTemplateParameters(compilation, files, options)
      oriReturn.globals.PREVIEW_URL = '/assets/storybook/iframe.html'
      return oriReturn
    }

    return config;
  }
};

you can replace /assets/storybook with your any prefix

Thanks

@brunomiguelbarrospinto
Copy link

I've just figured this out finally! To fully set the path prefix you need to set publicPath in both webpackFinal and managerWebpack functions in the .storybook/main.js like this:

// .storybook/main.js
module.exports = {
  webpackFinal: async (config, { configType }) => {
    config.output.publicPath = '/my-prefix/';
    return config;
  },
  managerWebpack: async (config) => {
    config.output.publicPath = '/my-prefix/';
    return config;
  },
};

Also, I had to build Storybook with the preview-url parameter to make it find the iframe file:

build-storybook -- --preview-url=/my-prefix/iframe.html

For some reason, I have found nothing about it in official docs, had to google it a lot...

Hey, thank you that's giving me hope about custom publicPath

In my case with Storybook version 6.2.9 I just need managerWebpack configuration and giving some extra config because --preview-url doesn't seem to works

// .storybook/main.js
module.exports = {
  managerWebpack: async (config) => {
    configHtmlWebPackPlugin = config.plugins.find(plugin => plugin.constructor.name === 'HtmlWebpackPlugin')
    configHtmlWebPackPlugin.options.publicPath = '/assets/storybook/'
    config.output.publicPath = '/assets/storybook/'
    const oriTemplateParameters = configHtmlWebPackPlugin.options.templateParameters
    configHtmlWebPackPlugin.options.templateParameters = (compilation, files, options) => {
      oriReturn = oriTemplateParameters(compilation, files, options)
      oriReturn.globals.PREVIEW_URL = '/assets/storybook/iframe.html'
      return oriReturn
    }

    return config;
  }
};

you can replace /assets/storybook with your any prefix

Thanks

Sorry, i cant understand this implementation, could you show the full implementation file? Thanks

@chornos13
Copy link

chornos13 commented Aug 30, 2021

I've just figured this out finally! To fully set the path prefix you need to set publicPath in both webpackFinal and managerWebpack functions in the .storybook/main.js like this:

// .storybook/main.js
module.exports = {
  webpackFinal: async (config, { configType }) => {
    config.output.publicPath = '/my-prefix/';
    return config;
  },
  managerWebpack: async (config) => {
    config.output.publicPath = '/my-prefix/';
    return config;
  },
};

Also, I had to build Storybook with the preview-url parameter to make it find the iframe file:

build-storybook -- --preview-url=/my-prefix/iframe.html

For some reason, I have found nothing about it in official docs, had to google it a lot...

Hey, thank you that's giving me hope about custom publicPath
In my case with Storybook version 6.2.9 I just need managerWebpack configuration and giving some extra config because --preview-url doesn't seem to works

// .storybook/main.js
module.exports = {
  managerWebpack: async (config) => {
    configHtmlWebPackPlugin = config.plugins.find(plugin => plugin.constructor.name === 'HtmlWebpackPlugin')
    configHtmlWebPackPlugin.options.publicPath = '/assets/storybook/'
    config.output.publicPath = '/assets/storybook/'
    const oriTemplateParameters = configHtmlWebPackPlugin.options.templateParameters
    configHtmlWebPackPlugin.options.templateParameters = (compilation, files, options) => {
      oriReturn = oriTemplateParameters(compilation, files, options)
      oriReturn.globals.PREVIEW_URL = '/assets/storybook/iframe.html'
      return oriReturn
    }

    return config;
  }
};

you can replace /assets/storybook with your any prefix
Thanks

Sorry, i cant understand this implementation, could you show the full implementation file? Thanks

Hey Bruno,
here is the simple implementation

.storybook/main.js

function injectCustomPublicPath(configWebpack, publicPath) {
  configWebpack.output.publicPath = publicPath
  configHtmlWebPackPlugin = configWebpack.plugins.find(
    (plugin) => plugin.constructor.name === 'HtmlWebpackPlugin',
  )
  configHtmlWebPackPlugin.options.publicPath = publicPath
  const oriTemplateParameters =
    configHtmlWebPackPlugin.options.templateParameters
  configHtmlWebPackPlugin.options.templateParameters = (
    compilation,
    files,
    options,
  ) => {
    oriReturn = oriTemplateParameters(compilation, files, options)
    oriReturn.globals.PREVIEW_URL = `${publicPath}iframe.html`
    return oriReturn
  }
}


module.exports = {
  managerWebpack: async (config) => {
    // change access url storybook to URL sub path ex: domain.com/assets/storybook
    injectCustomPublicPath(config, '/assets/storybook/')
    return config
  },
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests