In Vite, how do I specify a subdirectory of my server for the assets?
Asked Answered
S

3

7

I'm building a React app with Vite that is hosted in a subdirectory (/pwa) on my webserver.

The main site is a Drupal 10 site.

Previously, I was using Create React App to build my PWA. I have now converted the PWA to use Vite instead, but the problem is that when I run npm run build and copy the dist directory to /pwa on my server, looking for the assets fails because the build targets www.example.com/assets instead of www.example.com/pwa/assets.

How can I modify the vite config to tell it that I need the final output to look for assets in a subdirectory?

Selectman answered 27/3, 2023 at 15:36 Comment(0)
S
12

In Vite, this is called the base option.

In vite.config.ts:

// https://vitejs.dev/config/
export default defineConfig({
  base: '/pwa',
Selectman answered 28/3, 2023 at 2:8 Comment(2)
This answer seems unsatisfactory. The build should not have to know where it's hosted in order to work. Is there a way to get everything to simply link to a relative path?Sternlight
As far as I know, no.Selectman
F
4

You may use the base option.

If you're not sure where the app will deployed to, you may use a relative base like the following:

export default defineConfig({
  base:'./',
});
Fourscore answered 5/11, 2023 at 7:0 Comment(1)
Thanks for this. I'm not sure why this is not the default. I had figured out that I just needed to add the ./ at the start of the paths in my html file and was editing the build result manually. This is just what I needed.Truckage
N
2

Other answers show how to do this in a hard-coded way. For most applications, that's probably good enough. But if you want your build process to know nothing about external parameters and get them through the environment, then read this.

There are several ways to provide base_url: through the flag in your CI or through environment variables: .env, github actions, whatever.

Flag

Run vite build --base=/my/public/path/. The base URL should now be accessible from your code as import.meta.env.BASE_URL, so you can provide it to the router of your choice as the base:

const App = () => {
  return <Router base={import.meta.env.BASE_URL}>{...etc}</Router>;
};

Environment

For example, you can create an .env.production file and load it before running a build process. There are several ways to load .env files: dotenvy-cli, godotenv, dotenv-cli - just to name a few.

# .env.production file
BASE_URL="/subdir/"

# If you want to expose variables to your app, use `VITE_` prefix.
# BASE_URL doesn't require a prefix although it will be exposed because we're
# gonna use it in the config.
VITE_API_URI="https://example.com/api"
VITE_DEFAULT_LANG="en"
// vite.config.ts
export default defineConfig({
  // get exposed to your app as import.meta.env.BASE_URL
  base: getBase(),
  // rest of config
});

function getBase() {
  if (!process.env["BASE_URL"]) {
    throw new Error("BASE_URL environment variable is required");
  }
  return process.env["BASE_URL"];
}
Nonsuit answered 13/8 at 12:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.