Hotwire turbo_frame_tag doesn't work within table HTML tag

When using Hotwire's turbo_frame_tag inside a <table> HTML tag, it doesn't function as expected. This is because turbo_frame_tag inserts a custom HTML tag, which is not permitted within the <table> tag according to HTML specifications.

The Problem

HTML table structure is strict about what elements can appear inside a <table> tag. Only specific elements like <thead>, <tbody>, <tfoot>, <tr>, etc., are allowed as direct children of <table>.

When you try to use turbo_frame_tag inside a table:

<table>
  <turbo-frame id="user-row">
    <tr>
      <td>User Name</td>
    </tr>
  </turbo-frame>
</table>

This creates invalid HTML because <turbo-frame> is not a valid table element.

Why It Doesn't Work

The HTML specification requires that table elements follow a specific structure:

  • <table> can only contain: <caption>, <colgroup>, <thead>, <tbody>, <tfoot>, or <tr> (in some contexts)
  • Custom elements like <turbo-frame> violate this structure
  • Browsers may ignore or incorrectly render invalid table structures

Workarounds

Option 1: Wrap the Table

Instead of putting turbo_frame_tag inside the table, wrap the entire table:

<turbo-frame id="users-table">
  <table>
    <tbody>
      <tr>
        <td>User Name</td>
      </tr>
    </tbody>
  </table>
</turbo-frame>

Option 2: Use Turbo Streams

For updating individual rows, consider using Turbo Streams instead:

<!-- In your controller -->
respond_to do |format|
  format.turbo_stream
end
<!-- app/views/users/create.turbo_stream.erb -->
<%= turbo_stream.append "users-table", partial: "user_row", locals: { user: @user } %>

Option 3: Use JavaScript

For more complex interactions, you might need to use JavaScript to handle the updates:

import { Turbo } from "@hotwired/turbo-rails"

// Handle updates manually
document.addEventListener("turbo:frame-load", (event) => {
  // Custom logic for table updates
})

Best Practices

When working with tables and Turbo Frames:

  1. Wrap the entire table if you need to replace the whole table
  2. Use Turbo Streams for individual row updates
  3. Consider alternative layouts if frequent updates are needed
  4. Use proper HTML structure to maintain accessibility

Conclusion

While turbo_frame_tag is powerful for creating dynamic, updatable sections, it has limitations when working with HTML tables. Understanding these limitations helps you choose the right approach for your specific use case.

Hotwire turbo_frame_tag doesn't work within table HTML tag - Abhay Nikam