Search code examples
laravelinertiajslaravel-vite

Default Persistent Layout In Laravel + Inertia + Vite


In the previous way of setting up inertia in a laravel app, I could tweak the resolve property in the `createInertiaApp function from:

{
   ...,
   resolve: name => import("./Pages/${name}"),
   ...
}

To

{
   ...,
   resolve: name => {
    const page = require("./Pages/${name}").default
    if(!page.layout) {
     page.layout = DefaultLayoutFile
    }
   },
   ...
}

To allow me manually pass a default layout file to be used in pages.

But with Vite becoming the default asset bundler and according to the docs, I must use a resolvePageComponent function which takes in import.meta.glob as a second argument to instruct Vite which files to bundle.

Problem here is the import gets returned from this resolvePageComponent so I cannot access the default object like I normally will from a require function.

So I have not been able to attach a default layout file to imported pages.

Has anyone been able to find a workaround for this?


Solution

  • Assuming you imported your default layout file like this (remember to not use @ in imports anymore as only relative paths work for static analysis reasons):

    import DefaultLayoutFile from './Layouts/DefaultLayoutFile.vue'

    You can use the following code to get default layout working with Inertia and Vite:

      resolve: (name) => {
        const page = resolvePageComponent(
          `./Pages/${name}.vue`,
          import.meta.glob("./Pages/**/*.vue")
        );
        page.then((module) => {
          module.default.layout = module.default.layout || DefaultLayoutFile;
        });
        return page;
      },
    

    [UPDATE 2022-08-01]

    Since this is still receiving views, I though it would be useful to show how to get the @ working in imports in Vite.

    Require path below your imports in vite.config.js

    import { defineConfig } from 'vite';
    import laravel from 'laravel-vite-plugin';
    import vue from '@vitejs/plugin-vue';
    const path = require('path')
    

    And then add resolve into your config below:

    export default defineConfig({
      resolve:{
        alias:{
          '@' : path.resolve(__dirname, './src')
        },
      },
    })
    

    Now @ will point to your Laravel root and you can import components dynamically from anywhere:

    For example import LayoutTop from '@/Layouts/LayoutTop.vue' will now point to /resources/js/Layouts/LayoutTop.vue

    Remember that Vite needs the .vue extension when importing Vue SFC files.