Andy Jarrett // Code. Develop. Create.

Fixing Alpine.js Template Rendering Issues When Your Second Tag Isn't Showing

Photo by Ales Krivec on Unsplash

When working with Alpine.js templates, I ran into an issue where only the first child element inside a <template> tag is rendered, leaving subsequent elements mysteriously absent.

Understanding the Problem

Consider the following code:

<template x-if="products.product_id">
  <a :href="`/products/edit/${products.item_short_ref}/${products.item_code}`" class="px-2">
    Edit
  </a>
  <a :href="`/products/delete/${products.item_short_ref}/${products.item_code}`" class="px-2">
    Delete
  </a>
</template>

You might expect both <a> tags to render when the x-if condition is true. However, Alpine.js requires a single root element inside the <template> tag. If there are multiple sibling elements, only the first one will appear.

The Solution

To resolve this, wrap the content inside the <template> in a parent container, such as a <div> or <span>. Here’s the corrected code:

<template x-if="products.product_id">
  <span class="flex">
    <a :href="`/products/edit/${products.item_short_ref}/${products.item_code}`" class="px-2">
      Edit
    </a>
    <a :href="`/products/delete/${products.item_short_ref}/${products.item_code}`" class="px-2">
      Delete
    </a>
  </span>
</template>

The <span> acts as the single root node required by Alpine.js, allowing both <a> tags to render properly.

A Demo of the Issue and Solution

Here’s a simplified demonstration to illustrate the problem:

Code with Issue

<div x-data="{ open: false }">
  <button x-on:click="open = !open">Toggle 1 (shows one link only)</button>
  <template x-if="open">
    <a href="#">Link 1</a>
    <a href="#">Link 2</a>
  </template>
</div>

In this case, only "Link 1" will appear when you click the button.

Corrected Code

<div x-data="{ open: false }">
  <button x-on:click="open = !open">Toggle 2 (shows both links)</button>
  <template x-if="open">
    <div>
      <a href="#">Link 1</a>
      <a href="#">Link 2</a>
    </div>
  </template>
</div>

Now, both links will render correctly when the button is toggled.

I’m here, learning and working away. If you liked this content and want to keep me going, consider buying me a coffee. Your support keeps this site running and the coffee brewing! ☕️