Wrong laravel mix rewrite url path when place project in subfolder

Viewed 4221

I have deployed laravel react application on the server, inside a folder namely patients/ so the complete URL for the app is domain.com/patients

app.js and app.css files are not found, I am facing a 404 error, because it is trying to serve files from domain.com/ instead of domain.com/patients/app.css and domain.com/patients/app.js if I change mix to asset or place mix inside asset in app.blade.php then, all the other assets like 0.js, 0.css are not found,

following is the code in app.blade.php

<!DOCTYPE html>
<html class="h-full bg-gray-200">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <link href="{{ mix('/css/app.css') }}" rel="stylesheet">
    <script src="{{ mix('/js/app.js') }}" defer></script>
    <title>Clinical Laboratory | Provider Portal</title>
    @routes
</head>
<body class="font-sans leading-none text-gray-800 antialiased">

@inertia

</body>
</html>

following is my webpack.mix.js

const cssImport = require('postcss-import');
const cssNesting = require('postcss-nesting');
const mix = require('laravel-mix');
const path = require('path');
const purgecss = require('@fullhuman/postcss-purgecss');
const tailwindcss = require('tailwindcss');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix
  .react('resources/js/app.js', 'public/js')
  .postCss('resources/css/app.css', 'public/css/app.css')
  .options({
    postCss: [
      cssImport(),
      cssNesting(),
      tailwindcss('tailwind.config.js'),
      ...(mix.inProduction()
        ? [
            purgecss({
              content: [
                './resources/views/**/*.blade.php',
                './resources/js/**/*.js'
              ],
              defaultExtractor: content =>
                content.match(/[\w-/:.]+(?<!:)/g) || [],
              whitelistPatternsChildren: [/nprogress/]
            })
          ]
        : [])
    ]
  })
  .webpackConfig({
    output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
    resolve: {
      alias: {
        '@': path.resolve('resources/js')
      }
    }
  })
  .version()
  .sourceMaps();

I have also tried adding mix.setResourceRoot('/laravel/public/'); at the end

2 Answers

After a few struggle, I am able to resolve the issue, I have done the following changes

In .env added

APP_URL=http://localhost:8000

MIX_ASSET_URL=http://localhost:8000

and also added the following code in config/app.php

'mix_url' => env('MIX_ASSET_URL', null)

lastly, I have updated my webpack.mix.js and added public url in the output of webpackConfig

const cssImport = require('postcss-import');
const cssNesting = require('postcss-nesting');
const mix = require('laravel-mix');
const path = require('path');
const purgecss = require('@fullhuman/postcss-purgecss');
const tailwindcss = require('tailwindcss');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix
  .react('resources/js/app.js', 'public/js')
  .postCss('resources/css/app.css', 'public/css/app.css')
  .options({
    postCss: [
      cssImport(),
      cssNesting(),
      tailwindcss('tailwind.config.js'),
      ...(mix.inProduction()
        ? [
            purgecss({
              content: [
                './resources/views/**/*.blade.php',
                './resources/js/**/*.js'
              ],
              defaultExtractor: content =>
                content.match(/[\w-/:.]+(?<!:)/g) || [],
              whitelistPatternsChildren: [/nprogress/]
            })
          ]
        : [])
    ]
  })
  .webpackConfig({
    output: { chunkFilename: 'js/[name].js?id=[chunkhash]', publicPath: '/patients/' },
    resolve: {
      alias: {
        '@': path.resolve('resources/js')
      }
    }
  })
  .version()
  .sourceMaps();

Note: publicPath is added in the output property of webpackconfig. Hope it helps anyone else. Thanks

Its easier for me to change it in blade...

asset() will point to the folder namely patients/

then just substract the hash that mix() provides and concatenate with the asset url.

<link rel="stylesheet" href="{{asset('/css/app.css?' . explode('?', mix('/css/app.css'))[1])}}">
<script src="{{asset('/js/app.js?' . explode('?', mix('/js/app.js'))[1])}}"></script>
Related