Gatsby: Limit `pathPrefix` changes to assets only

Created on 29 Oct 2018  路  8Comments  路  Source: gatsbyjs/gatsby

Summary

  • We're passing the pathPrefix option primarily to access assets at the specified location on our server. The only issue is that this will also redirect to the path-prefixed version of the URL, which is not what we want.

Relevant information

  • Basically, we want to serve up all assets from the pathPrefixed version of the site, but not have it affect the routing. For example (assuming the pathPrefix were set to /assets):

    • User navigates to www.example.com/page-1

    • Internal routing (?) updates the URL to www.example.com/assets/page-1 for all requested routes.

  • I tried a couple different options, such as just overwriting the webpack config using gatsby-node.js to make the publicPath match the prefix, but I'm getting strange behavior there.
  • I think I've narrowed the issue down to the basepath variable for the Reach Router, which I need to have different behavior depending on the environment.
  • Our site uses standard Gatsby structure with all needed routes included in the /pages directory.

  • Is there a way to update the basepath variable using gatsby config?

  • Is there any other method for adding a prefix to just assets but maintaining the internal routing?
  • Is there a way to create a custom Router to control that functionality directly?

Let me know if additional information would be helpful. It's mostly just general questions that I haven't been able to track down any solutions for yet. Thanks!

stale? question or discussion

Most helpful comment

@thecox The primary use case of pathPrefix is for sites to be hosted somewhere other than the root of their domain. Say we have a Gatsby site at example.com/blog/. In this case, we would need a prefix (/blog) added to all paths on the site.

module.exports = {
  // Note: it must *not* have a trailing slash.
  pathPrefix: `/blog`,
}

If you want to prefix your assets with a path, then you will need to modify webpack configuration. That would look something like this:

exports.onCreateWebpackConfig = ({ actions, getConfig, stage }) => {
  if (stage === 'build-javascript') {
    const baseConfig = getConfig()
    const config = {
      ...baseConfig,
      ...{
        output: {
          // we need `path`, `filename` and `chunkFilename ` from original config
          // see https://github.com/gatsbyjs/gatsby/blob/f06f6c37698ccdd91b0f550fa30ab55f1d47cae9/packages/gatsby/src/utils/webpack.config.js#L129-L136
          ...baseConfig.output,
          publicPath: '/assets/',
        },
      },
    }
    actions.replaceWebpackConfig(config)
  }
}

Webpack documentation | Gatsby custom webpack config

/cc @pieh

All 8 comments

@thecox The primary use case of pathPrefix is for sites to be hosted somewhere other than the root of their domain. Say we have a Gatsby site at example.com/blog/. In this case, we would need a prefix (/blog) added to all paths on the site.

module.exports = {
  // Note: it must *not* have a trailing slash.
  pathPrefix: `/blog`,
}

If you want to prefix your assets with a path, then you will need to modify webpack configuration. That would look something like this:

exports.onCreateWebpackConfig = ({ actions, getConfig, stage }) => {
  if (stage === 'build-javascript') {
    const baseConfig = getConfig()
    const config = {
      ...baseConfig,
      ...{
        output: {
          // we need `path`, `filename` and `chunkFilename ` from original config
          // see https://github.com/gatsbyjs/gatsby/blob/f06f6c37698ccdd91b0f550fa30ab55f1d47cae9/packages/gatsby/src/utils/webpack.config.js#L129-L136
          ...baseConfig.output,
          publicPath: '/assets/',
        },
      },
    }
    actions.replaceWebpackConfig(config)
  }
}

Webpack documentation | Gatsby custom webpack config

/cc @pieh

Awesome, that makes a lot more sense to edit asset paths directly via webpack - I'll look into customizing the config as you mentioned. Thanks for the quick response! 馃檱

@thecox thanks for posting this question. Were you able to find out a good solution? I have the same use case as you. However, my pages have hrefs in the header which are still pointing to my root domain.

It seems like: static-entry.js sets the hrefs in tags in the header for for js, styles and json files and a lot of other assets.

For instance:

  scripts
    .slice(0)
    .reverse()
    .forEach(script => {
      // Add preload/prefetch <link>s for scripts.
      headComponents.push(
        <link
          as="script"
          rel={script.rel}
          key={script.name}
          href={`${__PATH_PREFIX__}/${script.name}`}
        />
      )
    })

If I'm not mistaken they need /asset to be prefixed in the same way __PATH_PREFIX__ is being added. adding publicPath to the webpack config doesn't change this. I am guessing that maybe script.name could change to accommodate /asset? Wondering if you were able to figure this one out.

@kakadiadarpan am I on the right track or am I missing something?

Thanks!

@hanchennz - Sorry for the delayed response. So I am still having issues with the prescribed method above and I believe you're correct in your assessment that there are other areas of the code that are making use of the prefix that no longer function without it.

It does seem that the only missing piece of functionality is the ability to access the router's basepath directly, or at least to customize the functionality there. @kakadiadarpan any additional thoughts on how this could be accomplished? Is there a way to use a custom router setup?

Old issues will be closed after 30 days of inactivity. This issue has been quiet for 20 days and is being marked as stale. Reply here or add the label "not stale" to keep this issue open!

Hey again!

It鈥檚 been 30 days since anything happened on this issue, so our friendly neighborhood robot (that鈥檚 me!) is going to close it.

Please keep in mind that I鈥檓 only a robot, so if I鈥檝e closed this issue in error, I鈥檓 HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

Thanks again for being part of the Gatsby community!

@thecox did you ever discover a solution for this? I'm struggling with the exact same problem!

@sami616 Sorry that this response is so late. Unfortunately, we had to abandon Gatsby due to the issue above. Our setup just wouldn't work without separating paths for assets without the client-side redirect. Looks like there's some work going on to resolve the issue above.

Still love Gatsby and use it on other projects, but a bummer that it wasn't a fit here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andykais picture andykais  路  3Comments

kalinchernev picture kalinchernev  路  3Comments

jimfilippou picture jimfilippou  路  3Comments

benstr picture benstr  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments