Automatic publicPath is not supported in this browser in production

Hi!

I’m having problems with getting an environment variable in JS on production. On development it works fine. What I’ve done is this.

use function Roots\bundle;

/**
 * Register the theme assets.
 *
 * @return void
 */
add_action('wp_enqueue_scripts', function () {
    bundle('app')->enqueue()->localize('SiteSettings', [
		'googleMapsApiKey' => getenv('GOOGLE_MAPS_API_KEY'),
		'markerIcon' => \Roots\asset('images/marker.png'),
	]);
}, 100);

And then in JS I access it like this

  loader: new Loader(SiteSettings.googleMapsApiKey),

In development it works fine, I get my API_KEY and can use it perfectly. But in production I get the error underneath. And I have tried the solutions in this post, but don’t seem to work for me, maybe I’m not implementing it correctly. (Automatic publicPath is not supported in this browser - #11 by kellymears)

Automatic publicPath is not supported in this browser

Can you set your public path?

In bud.config.js:

app.setPublicPath("/app/themes/sage/public/")

I tried this, but then the path is being appended and is trying to search in /app/themes/sage/public/app/themes/sage/public/.

What version of bud are you running? Post your package.json.

This site uses dynamic imports and is in production:

{
  "name": "@ndncollective/subsite",
  "version": "1.0.0",
  "license": "MIT",
  "private": true,
  "scripts": {
    "build": "bud build",
    "dev": "bud dev"
  },
  "devDependencies": {
    "@roots/bud": "5.8.4",
    "@roots/bud-sass": "5.8.4",
    "@roots/bud-tailwindcss": "5.8.4",
    "@roots/sage": "5.8.4"
  },
  "dependencies": {
    "@headlessui/react": "1.5.0",
    "@heroicons/react": "1.0.6",
    "@tailwindcss/aspect-ratio": "0.4.0",
    "@tailwindcss/forms": "0.5.0",
    "@tailwindcss/typography": "0.5.2",
    "@wordpress/base-styles": "^4.4.0",
    "@wordpress/block-library": "^7.5.0",
    "alpinejs": "3.9.6",
    "animejs": "3.2.1",
    "axios": "0.26.1"
  },
  "volta": {
    "node": "16.3.0"
  }
}
/**
 * @typedef {import('@roots/bud').Bud} bud
 *
 * @param {bud} app
 */
module.exports = async (app) => {
  app
    /**
     * Application entrypoints
     *
     * Paths are relative to your resources directory
     */
    .entry({
      app: ["@scripts/app", "@styles/app"],
      editor: ["@scripts/editor", "@styles/editor"],
    })
    .setPublicPath("/app/themes/subsite/public/")

    /**
     * These files should be processed as part of the build
     * even if they are not explicitly imported in application assets.
     */
    .assets([
      {
        from: app.path("@src/images"),
        to: app.path("@dist/images/@file"),
      },
      {
        from: app.path("@src/fonts"),
        to: app.path("@dist/fonts/@file"),
      },
    ])

    /**
     * Development URL to be used in the browser.
     */
    .proxy("http://redacted.test")
    .serve(3000)
    .watch(["./resources/views"]);
};

Setting my publicPath seems to work correctly in development. My staging environment is indeed running production at the moment to test things out.

Here is my Package.json.

{
  "name": "sage",
  "private": true,
  "browserslist": [
    "extends @wordpress/browserslist-config"
  ],
  "engines": {
    "node": ">=16.0.0"
  },
  "scripts": {
    "dev": "bud dev",
    "build": "bud build",
    "lint": "npm run lint:js && npm run lint:css",
    "lint:js": "eslint resources/scripts",
    "lint:css": "stylelint \"resources/**/*.{css,scss,vue}\"",
    "test": "npm run lint",
    "translate": "npm run translate:pot && npm run translate:js",
    "translate:pot": "wp i18n make-pot . ./resources/lang/sage.pot --ignore-domain --include=\"app,resources\"",
    "translate:js": "wp i18n make-json ./resources/lang --pretty-print"
  },
  "devDependencies": {
    "@roots/bud": "5.4.0",
    "@roots/bud-eslint": "5.4.0",
    "@roots/bud-prettier": "5.4.0",
    "@roots/bud-stylelint": "5.4.0",
    "@roots/bud-tailwindcss": "5.4.0",
    "@roots/eslint-config": "5.4.0",
    "@roots/sage": "5.4.0"
  },
  "dependencies": {
    "@alpinejs/collapse": "^3.9.2",
    "@fancyapps/fancybox": "^3.5.7",
    "@vidstack/player": "^1.4.0",
    "alpinejs": "^3.9.0",
    "axios": "^0.26.0",
    "google-maps": "^4.3.3",
    "lit": "^2.2.2"
  }
}

Bud.config.js

/**
 * @typedef {import('@roots/bud').Bud} bud
 *
 * @param {bud} app
 */
module.exports = async (app) => {
  app
    /**
     * Application entrypoints
     *
     * Paths are relative to your resources directory
     */
    .entry({
      app: ['@scripts/app', '@styles/app'],
      editor: ['@scripts/editor', '@styles/editor'],
    })
    .setPublicPath("/app/themes/tropaholic/public/")

    /**
     * These files should be processed as part of the build
     * even if they are not explicitly imported in application assets.
     */
    .assets('images')

    /**
     * These files will trigger a full page reload
     * when modified.
     */
    .watch([
      'tailwind.config.js',
      'resources/views/**/*.blade.php',
      'app/View/**/*.php',
    ])

    /**
     * Target URL to be proxied by the dev server.
     *
     * This is your local dev server.
     */
    .proxy('http://tropaholic.test')

    /**
     * Development URL
     */
    .serve('http://tropaholic.test:3000');
};

You should update everything to the latest version (5.8.4)

1 Like

Sorry I’m here again. I updated my package.json and changed my bud.config.js to the example you’ve shown me. Now everything seems to work, but the assets (images). These have the same problem as above, they are loaded like this example: http://staging.tropaholic.be/app/themes/tropaholic/public/app/themes/tropaholic/public/images/icons/profile.59e7af.svg

In my template I use the asset like this <img class="w-7" src="@asset('images/icons/profile.svg')" alt="Profile">. However the marker I’m using in Google Maps is being resolved using \Roots\asset('images/marker.png').

package.json

{
  "name": "sage",
  "private": true,
  "browserslist": [
    "extends @wordpress/browserslist-config"
  ],
  "engines": {
    "node": ">=16.0.0"
  },
  "scripts": {
    "dev": "bud dev",
    "build": "bud build",
    "lint": "npm run lint:js && npm run lint:css",
    "lint:js": "eslint resources/scripts",
    "lint:css": "stylelint \"resources/**/*.{css,scss,vue}\"",
    "test": "npm run lint",
    "translate": "npm run translate:pot && npm run translate:js",
    "translate:pot": "wp i18n make-pot . ./resources/lang/sage.pot --ignore-domain --include=\"app,resources\"",
    "translate:js": "wp i18n make-json ./resources/lang --pretty-print"
  },
  "devDependencies": {
    "@roots/bud": "5.8.4",
    "@roots/bud-eslint": "5.8.4",
    "@roots/bud-prettier": "5.8.4",
    "@roots/bud-stylelint": "5.8.4",
    "@roots/bud-tailwindcss": "5.8.4",
    "@roots/eslint-config": "5.8.4",
    "@roots/sage": "5.8.4"
  },
  "dependencies": {
    "@alpinejs/collapse": "^3.9.2",
    "@fancyapps/fancybox": "^3.5.7",
    "@vidstack/player": "^1.4.0",
    "alpinejs": "^3.9.0",
    "axios": "^0.26.0",
    "google-maps": "^4.3.3",
    "lit": "^2.2.2"
  }
}

bud.config.js

/**
 * @typedef {import('@roots/bud').Bud} bud
 *
 * @param {bud} app
 */
module.exports = async (app) => {
  app
    /**
     * Application entrypoints
     *
     * Paths are relative to your resources directory
     */
    .entry({
      app: ["@scripts/app", "@styles/app"],
      editor: ["@scripts/editor", "@styles/editor"],
    })
    .setPublicPath("/app/themes/tropaholic/public/")

    /**
     * These files should be processed as part of the build
     * even if they are not explicitly imported in application assets.
     */
    .assets([
      {
        from: app.path("@src/images"),
        to: app.path("@dist/images/@file"),
      },
      {
        from: app.path("@src/fonts"),
        to: app.path("@dist/fonts/@file"),
      },
    ])

    /**
     * Target URL to be proxied by the dev server.
     *
     * This is your local dev server.
     */
    .proxy('http://tropaholic.test')

    /**
     * Development URL
     */
    .serve('http://tropaholic.test:3000')

    /**
     * These files will trigger a full page reload
     * when modified.
     */
    .watch([
      'tailwind.config.js',
      'resources/views/**/*.blade.php',
      'app/View/**/*.php',
    ]);
};

Thanks in advance!

I always forget about the @asset directive.

You can set your publicPath like so:

app.entry({
  app: {
    import: ['@scripts/app', '@styles/app'],
    publicPath: '/app/themes/tropaholic/public/',
  },
})

And then remove the app.setPublicPath call.

This will ensure the public path is known to the client without throwing Acorn for a loop.

1 Like

When you update to 5.8.6, give app.setPublicPath another go. I think this issue is accounted for by the roots/sage plugin now.

1 Like

Seems to be working! Thanks for informing us for this update! :slight_smile: