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

Need a way to use static resources with router.base #4544

Closed
Loilo opened this Issue Dec 13, 2018 — with CMTY · 3 comments

Comments

Projects
None yet
2 participants
Copy link

Loilo commented Dec 13, 2018 — with CMTY

What problem does this feature solve?

Currently, there's no (documented) way to properly use static assets in sites deployed by Nuxt's generate command when the router.base coption is set to something other than /. Resources requested as ~/path/to/resource are correctly rewritten to [router.base]/path/to/resource. Unfortunately, there's no equivalent to that for static resources requested as /resource.


The real-world situation is simple:

  • We develop a site locally under http://localhost:3000/.
  • We want to deploy it as a static site to https://our-site.com/demo, so in production it gets the router.base option set to /demo.

Therefore in local development all static resources should point to / whereas in production they should point to /demo/.

I have created a minimal repro that explains this by example, much better than I could do here in words.

To kickstart the repro, just run:

npx github:Loilo/repro-nuxt-static-base

I believe this is the same issue that has been brought up in #2753.
It has been addressed with the introduction of the render.static.prefix option in #2755 which is however completely undocumented and it's unclear to me how it may solve the issue.

What does the proposed changes look like?

If the render.static.prefix option is actually able to solve this (which I think it's meant to be), it should be documented.

Otherwise, an additional render.static.* option could be introduced to control rewriting requests to static resources.

This feature request is available on Nuxt community (#c8302)
@manniL

This comment has been minimized.

Copy link
Member

manniL commented Jan 5, 2019

added an issue in the docs repo to document the render.static.prefix property.

It is by default set to true to move the static contents directly to the router.base.

nuxt.config.js

export default {
 router: { base: '/t' }
}

Accessing routes

/favicon.ico => /t/favicon.ico


Rewriting static content

<img src="a.jpg"> will be properly loaded

Caveat: <img src="/a.jpg"> will not be rewritten to /t/a.jpg because of the leading /

@manniL manniL closed this Jan 5, 2019

@manniL manniL reopened this Jan 5, 2019

@manniL manniL closed this Jan 5, 2019

@Loilo

This comment has been minimized.

Copy link

Loilo commented Jan 5, 2019

Thanks for taking care. For the record (and for possible future folks with the same problem), here's how we solved this issue in our project:

Rewriting regular URLs

For CSS url()s or <img> tags in templates, we use the (undocumented) static alias:

<img src="~static/a.jpg">

Rewriting dynamically created URLs

For cases where webpack cannot rewrite URLs due to dynamic data (e.g. <img :src="filename">), we defined an additional global constant and use it like this:

<img :src="`${STATIC_PATH}/${filename}`">

Making STATIC_PATH available is a little more work. Part of it was adjusting our nuxt.config.js:

const PRODUCTION_BASE_PATH = '/demo';

module.exports = {

  // ...

  // Set the router's base path
  router: {
    base: process.env.NODE_ENV === 'production'
      ? PRODUCTION_BASE_PATH
      : '/'
  },

  // ...

  // Rewrite all occurrences of STATIC_PATH
  build: {
    extend(config, { isDev }) {
      config.plugins.push(new webpack.DefinePlugin({
        STATIC_PATH: JSON.stringify(isDev ? '' : PRODUCTION_BASE_PATH)
      }))
    }
  },

  // ...

  // Make STATIC_PATH available in Vue templates
  plugins: [ '~/plugins/static-mixin.js' ],

  // ...

};

This defines the global STATIC_PATH to equal /demo in production while being an empty string in development.

To make it available in Vue templates, we added the plugins/static-mixin.js, which defines a global mixin and looks like this:

import Vue from 'vue'

Vue.mixin({
    computed: {
        STATIC_PATH: () => STATIC_PATH
    }
})
@manniL

This comment has been minimized.

Copy link
Member

manniL commented Jan 5, 2019

@Loilo Thanks for sharing! 👍

Small suggestion: You could use env to make the static path available in Vue components too so you don't have the "burden" of a global mixin ☺️

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