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

app_dev's avatar

Can you tell me how to use inertia vue 3 with external script?

This external script - Tailwind Preline theme mode change button js (thememode.js)

const HSThemeAppearance = {
    init() {
        const defaultTheme = 'default'
        let theme = localStorage.getItem('hs_theme') || defaultTheme

        if (document.querySelector('html').classList.contains('dark')) return
        this.setAppearance(theme)
    },
    _resetStylesOnLoad() {
        const $resetStyles = document.createElement('style')
        $resetStyles.innerText = `*{transition: unset !important;}`
        $resetStyles.setAttribute('data-hs-appearance-onload-styles', '')
        document.head.appendChild($resetStyles)
        return $resetStyles
    },
    setAppearance(theme, saveInStore = true, dispatchEvent = true) {
        const $resetStylesEl = this._resetStylesOnLoad()

        if (saveInStore) {
            localStorage.setItem('hs_theme', theme)
        }

        if (theme === 'auto') {
            theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'default'
        }

        document.querySelector('html').classList.remove('dark')
        document.querySelector('html').classList.remove('default')
        document.querySelector('html').classList.remove('auto')

        document.querySelector('html').classList.add(this.getOriginalAppearance())

        setTimeout(() => {
            $resetStylesEl.remove()
        })

        if (dispatchEvent) {
            window.dispatchEvent(new CustomEvent('on-hs-appearance-change', {detail: theme}))
        }
    },
    getAppearance() {
        let theme = this.getOriginalAppearance()
        if (theme === 'auto') {
            theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'default'
        }
        return theme
    },
    getOriginalAppearance() {
        const defaultTheme = 'default'
        return localStorage.getItem('hs_theme') || defaultTheme
    }
}
HSThemeAppearance.init()

    const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

  try {
    // Chrome & Firefox
    darkMediaQuery.addEventListener('change', (e) => {
        if (HSThemeAppearance.getOriginalAppearance() === 'auto') {
            HSThemeAppearance.setAppearance('auto', false)
        }
    });
  } catch (e1) {
    try {
      // Safari
      darkMediaQuery.addListener((e) => {
        if (HSThemeAppearance.getOriginalAppearance() === 'auto') {
            HSThemeAppearance.setAppearance('auto', false)
        }
      });
    } catch (e2) {
      console.error(e2);
    }
  }

window.addEventListener('load', () => {
    const $clickableThemes = document.querySelectorAll('[data-hs-theme-click-value]')
    const $switchableThemes = document.querySelectorAll('[data-hs-theme-switch]')

    $clickableThemes.forEach($item => {
        $item.addEventListener('click', () => HSThemeAppearance.setAppearance($item.getAttribute('data-hs-theme-click-value'), true, $item))
    })

    $switchableThemes.forEach($item => {
        $item.addEventListener('change', (e) => {
            HSThemeAppearance.setAppearance(e.target.checked ? 'dark' : 'default')
        })

        $item.checked = HSThemeAppearance.getAppearance() === 'dark'
    })

    window.addEventListener('on-hs-appearance-change', e => {
        $switchableThemes.forEach($item => {
            $item.checked = e.detail === 'dark'
        })
    })
})

vite include code in app.blade.php head tag

@vite(['resources/css/app.css', 'resources/js/app.js', 'public/exscript/thememode.js', "resources/js/Pages/{$page['component']}.vue"])

laravel plugin code in vite.config.js

input: ['resources/js/app.js', 'public/exscript/thememode.js', 'resources/css/app.css'],

The problem is; The theme mode change button works when the page is loaded. But when navigating the intertia routes, the button does not work. Is it wrong to add js prepared by Preline with vite? Do you have another management? As I understand it the script works the first time but it gets lost in the intertia routes. Vue or intertia script can't follow?

0 likes
3 replies
biskoot's avatar
biskoot
Best Answer
Level 1

I had the same problem but find a workaround by wrapping the Preline plugin method using MutationObserver. Hope this helps.

// resources/js/app.js
import { HSDropdown } from 'preline'

// First init element when page load
HSDropdown.autoInit()

// Re-init element when page change through Inertia route
const observer = new MutationObserver((mutationsList) => {
    for (const mutation of mutationsList) {
        HSDropdown.autoInit()
    }
});

// Start observing the changes on the document body
observer.observe(document.body, { attributes: true, subtree: true, childList: true, characterData: true });
2 likes
federicko94's avatar

hello,

I have problem with this package and i can not run properly , As you may know, this is an Inertia configuration:

import './bootstrap';
import '../css/app.css';

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from '../../vendor/tightenco/ziggy';

const appName = import.meta.env.VITE_APP_NAME || 'Laravel';

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    setup({ el, App, props, plugin }) {
        return createApp({ render: () => h(App, props) })
            .use(plugin)
            .use(ZiggyVue)
            .mount(el);
    },
    progress: {
        color: '#4B5563',
    },
});

and this is my vite configuration

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

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.js',
            ssr: 'resources/js/ssr.js',
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    server: {
        https: false,
        host: true,
        hmr: { 
            host: 'localhost',
            protocol: 'ws',
        },
    },
});

I was trying use the solution of @biskoot but i can't run properly

federicko94's avatar

the problem was that I defined the plugins section twice in tailwind.config.js

Please or to participate in this conversation.