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

wojakmcwagies's avatar

<svelte:head> and <slot /> not changing after login (Laravel Inertia Svelte)

I'm implementing an authentication system in my Laravel Inertia Svelte app using Laravel Fortify. I already got the login, forgot password, etc working properly. But it seems anything inside svelte:head like meta, title, etc and the isn't working after the user logged in.

Here is how my Login Page looks like: https://ibb.co/v4JRcfQ

As you can see from the image above, the Login Page looks like that and it load meta tag and asset from svelte:head properly.

Then after the user input email and password. He logged in and got redirected without reload to the Index Page. The Index page itself looks like this: https://ibb.co/DrdnnW1

As you can see, there is no meta tag or anything like that. Also the <slot /> isn't get loaded. This is how it's supposed to look like (I need to reload the whole page for this to show): https://ibb.co/D42DH0T

This is my GuestLayout (layout for non-login user) code:

<script>
    const currentYear = new Date().getFullYear();
</script>

<div class="auth-page-wrapper pt-5">
    <div class="auth-page-content">
        <div class="container">
            <div class="row">
                <div class="col-lg-12">
                    <div class="text-center mt-sm-5 mb-4 text-white-50">
                        <div>
                            <a href="index.html" class="d-inline-block auth-logo">
                                <img src="assets/images/logo-light.png" alt="logo-light.png" height="20">
                            </a>
                        </div>
                    </div>
                </div>
            </div>

            <div class="row justify-content-center">
                <div class="col-md-8 col-lg-6 col-xl-5">
                    <slot />
                </div>
            </div>
        </div>
    </div>

    <footer class="footer">
        <div class="container">
            <div class="row">
                <div class="col-lg-12">
                    <div class="text-center">
                        <p class="mb-0 text-muted">
                            &copy; {currentYear} Velzon. Crafted with <i class="mdi mdi-heart text-danger"></i> by Themesbrand
                        </p>
                    </div>
                </div>
            </div>
        </div>
    </footer>
</div>

This is the Login Page itself:

<script context="module">
    export { default as layout } from '../../Layouts/GuestLayout.svelte';
</script>

<script>
    import { inertia, useForm } from '@inertiajs/svelte';

    let form = useForm({
        email: null,
        password: null,
        remember: false,
    });

    function login() {
        $form.post('/login');
    }
</script>

<svelte:head>
    <title>Login</title>
    <meta name="description" content="Login Page">

    <script src="/assets/js/pages/password-addon.init.js" defer></script>
</svelte:head>

<div class="card mt-4 card-bg-fill">
    <div class="card-body p-4">
        <div class="text-center mt-2">
            <h5 class="text-primary">Welcome Back !</h5>
            <p class="text-muted">Sign in to continue to Velzon.</p>
        </div>
        <div class="p-2 mt-4">
            <form on:submit|preventDefault={login}>
                <div class="mb-3">
                    <label for="username" class="form-label">Email</label>
                    <input type="text" class="form-control" class:is-invalid={$form.errors.email} id="username" bind:value={$form.email} placeholder="Enter email">
                    {#if $form.errors.email}
                        <div class="invalid-feedback">{$form.errors.email}</div>
                    {/if}
                </div>
                <div class="mb-3">
                    <div class="float-end">
                        <a use:inertia href="/forgot-password" class="text-muted">Forgot password?</a>
                    </div>
                    <label class="form-label" for="password-input">Password</label>
                    <div class="position-relative auth-pass-inputgroup mb-3">
                        <input type="password" class="form-control pe-5 password-input" class:is-invalid={$form.errors.password} bind:value={$form.password} placeholder="Enter password" id="password-input">
                        <button class="btn btn-link position-absolute end-0 top-0 text-decoration-none text-muted password-addon" type="button" id="password-addon"><i class="ri-eye-fill align-middle"></i></button>
                        {#if $form.errors.password}
                            <div class="invalid-feedback">{$form.errors.password}</div>
                        {/if}
                    </div>
                </div>
                <div class="form-check">
                    <input class="form-check-input" type="checkbox" id="auth-remember-check" bind:checked={$form.remember}>
                    <label class="form-check-label" for="auth-remember-check">Remember me</label>
                </div>
                <div class="mt-4">
                    <button class="btn btn-primary w-100" type="submit" disabled={$form.processing}>Sign In</button>
                </div>
            </form>
        </div>
    </div>
</div>

This is the AuthenticatedLayout (layout for logged-in user) code:

<script>
    import LayoutFooter from '../Components/LayoutFooter.svelte';
    import LayoutHeader from '../Components/LayoutHeader.svelte';
    import LayoutSidebar from '../Components/LayoutSidebar.svelte';

</script>
<div id="layout-wrapper">

    <LayoutHeader />

    <LayoutSidebar />

    <div class="main-content">

        <div class="page-content">
            <div class="container-fluid">

                <slot />

            </div>
        </div>

        <LayoutFooter />
    </div>
</div>

And finally this is the Index Page:

<script context="module">
    export { default as layout } from '../Layouts/AuthenticatedLayout.svelte';
</script>

<svelte:head>
    <title>Index</title>
    <meta name="description" content="Index Page">

    <script src="/assets/js/app.js" defer></script>
</svelte:head>

<div class="row">
    <div class="col-12">
        <div class="page-title-box d-sm-flex align-items-center justify-content-between">
            <h4 class="mb-sm-0">Index</h4>

            <div class="page-title-right">
                <ol class="breadcrumb m-0">
                    <li class="breadcrumb-item">Dashboard</li>
                    <li class="breadcrumb-item active">Index</li>
                </ol>
            </div>

        </div>
    </div>
</div>

I already make sure that the path to the layout is correct. So I don't get it how the svelte:head that contains title, meta tags, etc and also the <slot /> doesn't show up. Only the AuthenticatedLayout that seems to be correct after logged in. Can anyone please help me?

0 likes
2 replies
wojakmcwagies's avatar

UPDATE:

I've narrowed down the problem. It seems that persistent layout doesn't work if you need to change the layout midway. Like in the case where if you're logged in (AuthenticatedLayout) and you want to logout to the Login Page (GuestLayout). Since it's two different layout, it won't work.

I still wanted the benefit of persistent layout tho, so if anyone knows how to do that, please help me. Thank you.

Please or to participate in this conversation.