Troubleshooting

Overview

As you use CBWIRE, you are likely to run into issues from time to time. The most common issues are rendering issues. Here, we try to address the most common problems and show how to solve them.

CBWIRE

Lazy-loaded components with placeholders don't render

Consider the following widget example.

// ./wires/Widget.cfc
component extends="cbwire.models.Component" {
    function placeholder() {
        return "<section>put spinner here...</section>";
    }
}
<!--- ./wires/widget.cfm --->
<cfoutput>
    <div>
        <h1>My Widget</h1>
    </div>
</cfoutput>

Let's include our widget somewhere on our site and add lazy loading.

<cfoutput>#wire( name="Widget", lazy=true )#</cfoutput>

What should happen on page load is our placeholder is shown first, and then our widget renders to the page. Instead, we get a weird error like this.

Snapshot missing on Livewire component with id K8SDFLSDF902KSDFLASKJFASDFLJ.

The Livewire JavaScript error isn't super helpful in identifying the problem because the real issue is a mismatch between your widget's outer element and its placeholder's outer element.

Notice our widget's template above has an outer <div> but our placeholder has an outer <section> element. This will not work. Your placeholder and your corresponding template must have the same outer element. Otherwise, Livewire's DOM diffing engine gets confused.

The fix would be to make them both have outer <div> tags.

// ./wires/Widget.cfc
component extends="cbwire.models.Component" {
    function placeholder() {
        return "<div>put spinner here...</div>";
    }
}
<!--- ./wires/widget.cfm --->
<cfoutput>
    <div>
        <h1>My Widget</h1>
    </div>
</cfoutput>

Alpine.js

Nothing is working

While Alpine is lightweight and simple to use, it's easy to get tripped up when getting started.

See if you can spot what is wrong with this code.

<!--- ./wires/counter.cfm --->
<cfoutput>
    <div
        x-data="{
            name: "CBWIRE"
        }">
        <div>Name: <span x-text="name"></span></div>
    </div>
</cfoutput>

The code above will result in a JavaScript error.

The problem is our use of double quotes for our name property. Because our x-data block is surrounded by double quotes, using double quotes inside the block isn't proper syntax.

Change to using single quotes instead, and all is well again.

<!--- ./wires/counter.cfm --->
<cfoutput>
    <div
        x-data="{
            name: 'CBWIRE'
        }">
        <div>Name: <span x-text="name"></span></div>
    </div>
</cfoutput>

We recommend always using single quotes inside your x-data block.

Unable to find component error

You can run into rendering issues when using Alpine's <template> tag with an x-if if you are also including a component within the tag using wire().

For example:

<cfoutput>
    <div x-data="{
        loading: false,
        async init() {
            this.loading = true
            await $wire.someAction()
            this.loading = false
        }
    }">
        <template x-if="loading">
            #wire( "Spinner" )#
        </template>
    </div>
</cfoutput>

As you toggle the loading value from true to false, you may see a JavaScript error similar to this. The component ID will be different

Unable to find component K8SDFLSDF902KSDFLASKJFASDFLJ.

The issue above is that Alpine.js' x-if directive completely removes the contents inside from the DOM and recreates them when true. Livewire.js' DOM diffing engine is expecting the spinner to be there, and it can't find it, hence the error.

Luckily, the simple fix is to change your <template x-if> to something like a <div> and use x-show instead.

<cfoutput>
    <div x-show="loading">
        #wire( "Spinner" )
    </div>
</cfoutput>

You'll still achieve the desired result and Livewire.js can track the spinner accurately.

Last updated