empire29
empire29

Reputation: 3890

React/vite app with base URL that does not apply to static links in the main HTML file

I have a question, around base urls. I have a React/Vite application that will get deployed into a webserver that hosts many other web-properties, and as part of this, all web-properties include shared JS and CSS. These shared JS/CSS are all served off the root do the domain (ex. https://www.my-domain.com/assets/shared.js). These includes are just hard coded into my main HTML file (usually index.html, but in my case root.html)

My React app however is served from https://www.my-domain.com/apps/catalog/root.html. If i run my app locally with just npm run dev, everything works - but but my app is served off the root. I thought the right way to have this all run off my /apps/catalog/ based URL was to run all my vite commands with --base=/apps/catalog which seems to almost work; the problem is it rewrites thee static shared includes, which break them, since theyre expected to be served off the root.

I think, i need to figure out how to mark specific includes as not being effected by the base URL rewrite? Or, is there a better way to approach this?

My HTML file w/ the static includes of the "shared" assets. I dont want to hardcode the "real" domain in the src URLs since then my local proxy can't trap them and grab them serverside preventing CORS issues.

// /src/root.html
<html>
   <head>
      <!-- served from: https://www.my-domain.com/assets/shared.js -->
      <script src="/assets/shared.js"/> 
      <!-- served from: https://www.my-domain.com/api/shared.js -->
      <script src="/api/shared.js"/>
      .. etc ..
    </head>
    <div id="app"></div>
</html>

My vite.config.js where i start to try to introduce the notion of a base url (and a non-index.html named "main" file)

The local proxy so these static includes resolved without CORS issues, for local dev (it proxies these static assets out to the Shared host, and everything works well locally).

// src/vite.config.js
export default defineConfig({
  plugins: [react()],
  build: {
    assetsDir: 'static-assets',
    rollupOptions: {
      input: {
        app: './root.html',
      },
    },
  },
  base: '/apps/catalog/',
  server: {
    open: '/root.html',
    proxy: {
      '^/assets/.*|^/api/.*': {
          target: 'https://www.my-domain.com',
          changeOrigin: true
      }
    }
  }
})

And my package.json where i tried to also set the base URL.

// package.json scripts
"dev": "vite --base=/apps/catalog/",
"build": "vite build --base=/apps/catalog/"

Upvotes: 3

Views: 7235

Answers (1)

PiTheNumber
PiTheNumber

Reputation: 23552

I had the same problem with Laravel 9 + vite v3.2.5.

I fixed it (after hours) with the experimental renderBuiltUrl:

import {defineConfig, loadEnv} from 'vite';
// load env variables to get base url
process.env = Object.assign(process.env, loadEnv('production', process.cwd(), ''));

export default defineConfig({
  // ...
  experimental: {
    renderBuiltUrl(filename) {
        // here we set the base url. You might have to change this for react:
        return process.env.APP_URL + '/build/' + filename;
    }
  }
}

Note the warning in the documentation:

This feature is experimental, the API may change in a future minor without following semver. Please always pin Vite's version to a minor when using it.

Upvotes: 0

Related Questions