Scroll to the First Error Message with Livewire 3.x

livewire
Table of Contents

When submitting a form with Livewire, you probably want to render out some error messages and show them to your user. A nice enhancement is automatically scrolling to the first error message on the page.

First, make sure that the element that renders the error message has some sort of "marker" class or data attribute that marks it as an error message.

@error('name')
    <p class="error-message text-danger-red">
        {{ $message }}
    </p>
@enderror

Now inside of a <script> tag, you can write the following code.

Livewire.hook('commit', ({ succeed }) => {
    succeed(() => {
        setTimeout(() => {
            const firstErrorMessage = document.querySelector('.error-message')

            if (firstErrorMessage !== null) {
                firstErrorMessage.scrollIntoView({ block: 'center', inline: 'center' })
            }
        }, 0)
    })
}) 

Using Livewire's JavaScript API you can hook into the lifecycle of a request. The commit hook can be used to do something during the lifecycle of a single commit.

A callback provided to the succeed() function will be invoked once the commit has been processed by Livewire. Then on the next tick in the event loop, you can check for an error message element and scroll it into view.

If you're using Alpine, you can place this piece of code into the init() method or x-init directive and instead of calling setTimeout with a duration of 0, use the $nextTick magic method which has the same outcome.

<form x-data="{
    init() {
        Livewire.hook('commit', ({ succeed }) => {
            succeed(() => {
                this.$nextTick(() => {
                    const firstErrorMessage = document.querySelector('.error-message')

                    if (firstErrorMessage !== null) {
                        firstErrorMessage.scrollIntoView({ block: 'center', inline: 'center' })
                    }
                })
            })
        })
    }
}">

Enjoyed this post or found it useful? Please consider sharing it on Twitter.