Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

BernardoBF4's avatar

Dynamic Imports for CSS and Vite

Reading the Vite documentation I got to now it allows for dynamic importing of assets. I think that's really cool, only if I could make it work.

As far as I know, this concept is about being able to use on each page only the CSS (and JS) you need for that page, ranking better on SEO and page speed, but I all my CSS is compiled together in an app.scss file.

So could I make it work? Also, if this can also apply to Vue, I'd be glad to know how to make it work for Vue too.

This is my Vite configuration file.

import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue2';

export default defineConfig({
  server: {
    host: true,
    hmr: {
      host: 'localhost',
    },
  },
  plugins: [
    laravel({
      input: [
        'resources/assets/sass/app.scss',
        'resources/assets/js/app.js',
        'resources/assets/js/cms/app.js',
        'resources/assets/js/front/app.js'
      ],
      refresh: true,
    }),
    vue(),
  ],

});

On app.blade.php I import my Vite resources like this:

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">

<head>
  <meta charset="utf-8">
  <meta content="IE=edge" http-equiv="X-UA-Compatible">
  <meta content="noindex" name="robots" />
  <link href="{{ url('img/logo.png') }}" rel="icon">

  <meta content="{{ csrf_token() }}" name="csrf-token">

  <title>{{ config('app.name', 'Laravel') }}</title>
  <!-- Tell the browser to be responsive to screen width -->
  <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">

  <!-- Styles -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js"></script>
  <script src="{{ asset('node_modules/tinymce/tinymce.js') }}"></script>
  @vite(['resources/assets/sass/app.scss', 'resources/assets/js/app.js', 'resources/assets/js/cms/app.js', 'node_modules/admin-lte/dist/js/adminlte.min.js'])
</head>

@yield('body')
<script>
  $(document).ready(function() {
    $('[data-toggle="tooltip"]').tooltip();
  });
</script>

</html>

0 likes
1 reply
LaryAI's avatar
Level 58

To use dynamic imports for CSS in Vite, you can split your app.scss file into smaller files that correspond to specific pages or components. Then, you can import those files dynamically using Vite's import() function.

Here's an example of how you can modify your Vite configuration file to use dynamic imports for CSS:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue2';

export default defineConfig({
  server: {
    host: true,
    hmr: {
      host: 'localhost',
    },
  },
  plugins: [
    laravel({
      input: [
        'resources/assets/js/app.js',
        'resources/assets/js/cms/app.js',
        'resources/assets/js/front/app.js'
      ],
      refresh: true,
    }),
    vue(),
  ],
  build: {
    rollupOptions: {
      input: {
        app: 'resources/assets/sass/app.scss',
        home: 'resources/assets/sass/home.scss',
        about: 'resources/assets/sass/about.scss',
        contact: 'resources/assets/sass/contact.scss',
      },
    },
  },
});

In this example, we've added a build property to the configuration object, which contains a rollupOptions property. The rollupOptions property specifies the input files for Rollup, which is the bundler that Vite uses under the hood.

We've specified four input files, one for each page that we want to load CSS for. These files are located in the resources/assets/sass directory, and have the .scss extension.

To import these files dynamically, you can use the import() function in your Vue components or pages. Here's an example of how you can import the home.scss file in a Vue component:

<template>
  <div class="home">
    <h1>Welcome to the home page</h1>
  </div>
</template>

<script>
export default {
  async mounted() {
    const { default: styles } = await import('/build/home.css');
    styles.use();
  },
};
</script>

In this example, we're using the async/await syntax to load the home.css file dynamically. We're importing the file from the /build directory, which is where Vite outputs the compiled CSS files.

Once the file is loaded, we're calling the use() method on the styles object to apply the CSS to the current page.

Note that you'll need to modify your app.blade.php file to remove the @vite directive, since you're now importing CSS dynamically. You can also remove the resources/assets/sass/app.scss file from your Vite configuration, since it's no longer needed.

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">

<head>
  <meta charset="utf-8">
  <meta content="IE=edge" http-equiv="X-UA-Compatible">
  <meta content="noindex" name="robots" />
  <link href="{{ url('img/logo.png') }}" rel="icon">

  <meta content="{{ csrf_token() }}" name="csrf-token">

  <title>{{ config('app.name', 'Laravel') }}</title>
  <!-- Tell the browser to be responsive to screen width -->
  <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">

  <!-- Styles -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js"></script>
  <script src="{{ asset('node_modules/tinymce/tinymce.js') }}"></script>
</head>

@yield('body')
<script>
  $(document).ready(function() {
    $('[data-toggle="tooltip"]').tooltip();
  });
</script>

</html>

Please or to participate in this conversation.