When using vapor deploy the assets (images) are not uploaded to the CDN.
The images themselves are inside .vue files. Mix/Webpack is rewriting the URLs, but not using the publicPath variable supplied via Vapor to serve them from cloudfront, the images themselves are copied to cloudfront.
For example, a vue file: Login.vue in resources/js/views/Login.vue has the following tag:
<img src="../../images/logos/logo.png" alt="Logo" class="w-32 m-auto mb-5" />
Which related to a file in /resources/images/logos/logo.png.
When npm run dev is executed, this is rewritten to /images/logo.png, and logo.png is copied to /public/images/logo.png as expected. When served locally this works fine.
However, when using the following code in webpack.mix.js (as taken from the Laravel Vapor docs) to inject a publicPath variable for serving the assets:
const ASSET_URL = process.env.ASSET_URL + "/";
mix.webpackConfig(webpack => {
return {
plugins: [
new webpack.DefinePlugin({
"process.env.ASSET_PATH": JSON.stringify(ASSET_URL)
})
],
output: {
publicPath: ASSET_URL
}
};
});
It seems to completely ignore the publicPath output and still just rewriting the URL to /images/logo.png. The expected result is for it to prepend the ASSET_URL/publicPath provided. I have console.log() the ASSET_URL during a npm run dev(/production) and the URL is outputted correctly, so the issue is getting webpack/laravel-mix to actually using that in the complied source.
Using mix() inside blade files works as expected, but the image URLs are inside Vue files so webpack/laravel-mix needs to do the injecting.
Not sure if this is a bug or we're doing something wrong, but seemingly have tried everything.
Same issue here. I have a slightly different setup because I'm using tailwindcss also. For this reason, I had to turn "processCssUrls" off.
/* https://tailwindcss.com/docs/installation#laravel-mix */
processCssUrls: false,
We're using Tailwinds CSS too, had to disable processCssUrl for that reason. But even with that enabled it wouldn't fix it in the Vue.
Found a work around, but it's not pretty. Credit - https://kevinchoppin.dev/blog/adding-your-cdn-to-image-references-in-js-and-css-with-laravel-mix
mix.imgCDN = function (path, cdn) {
let file = new File(path);
// Replace all occurrences of /images/ with CDN URL prepended
let contents = file.read().replace(/\/images\//g, cdn+"/images/");
file.write(contents);
// Update version hash in manifest
Mix.manifest.hash(file.pathFromPublic()).refresh();
return this;
}.bind(mix);
mix.then(function(){
let cdn = process.env.ASSET_URL;
if (cdn !== undefined) {
mix
.imgCDN('public/css/app.css', cdn)
.imgCDN('public/js/app.js', cdn);
}
});
Basically do a massive search and replace in the code to find any instance of "/images/" and replace it with the CDN URL. It just seems like a really blunt tool - I wish mix/Webpack supported it correctly,
Thanks, will use this, for now, not pretty but better than missing images :)
I spent far too much time looking into this and trying various combinations of suggested solutions. In the end, the solution was extremely simple. You just need to use setResourceRoot. (The setPublicPath method is super misleading and doesn't work.)
In my case, setting the output: { publicPath: ... } config is not necessary. Combine your webpack custom configs with this:
const ASSET_URL = `${process.env.ASSET_URL || ''}/`
mix.setResourceRoot(ASSET_URL)
It is working for me now to deploy my React project with full image URLs.
I'm using Vue, the images were missing the CDN's path only in .vue files
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Issue needs te be opened
problem is still there
I found this section of the Vapor documentation very helpful: https://docs.vapor.build/1.0/projects/deployments.html#assets
anyone has an idea how you would replace image path in a manifest file for vapor?
like: manifest.webmanifest
Following the instructions on Vapor resolved the CSS and JS assets loading from the CDN. Then following @joelvh's instructions for using mix.setResourceRoot resolved assets being imported from within JS.
Most helpful comment
Issue needs te be opened
problem is still there