I have an index page that shows multiple shipment cards. I want to wrap each of these shipments in a link_to that will visit the show page of the shipment. For some reason, when I inspect the HTML in my browser dev tools I can see that the link_to renders multiple times and the tags that gets generated does not surround the card as expected. What am I doing wrong?
Here is my code:
<%= render Atoms::PageLayoutComponent.new(header: "Orders") do |page_layout| %>
<% page_layout.with_header_slot do %>
<%= render Ui::Shipment::ShipmentFiltersComponent.new(shipments: @shipments) %>
<% end %>
<% page_layout.with_page_content do %>
<%= turbo_frame_tag "reseller_shipments_results" do %>
<div class="grid gap-3">
<% @shipments.each do |shipment| %>
<div class="grid grid-cols-1 gap-0.5 lg:grid-cols-[75%_25%] lg:gap-2">
<%= link_to reseller_shipment_path(shipment.shipment_reference), data: { turbo_frame: "_top" } do %>
<%= render Ui::ShipmentComponent.new(shipment:) %>
<% end %>
<%= render Ui::InvoiceTogglesComponent.new(shipment:) %>
</div>
<% end %>
</div>
<% end %>
<div class="grid place-content-center">
<%== pagy_nav(@pagy) %>
</div>
<% end %>
<% end %>
An example of the HTML:
<div class="grid grid-cols-1 gap-0.5 lg:grid-cols-[75%_25%] lg:gap-2">
<a data-turbo-frame="_top" href="/reseller/shipments/123"> </a>
<div class="rounded bg-white p-3 shadow hover:shadow-lg transition-all duration-200">
<a data-turbo-frame="_top" href="/reseller/shipments/123"> </a>
<div class="grid gap-2 text-neutral-300 text-xs">
<a data-turbo-frame="_top" href="/reseller/shipments/123">
<div class="flex justify-between">
<div class="flex gap-2 flex-wrap items-center">
<div class="text-neutral-500 font-semibold">
xxxx
</div>
<div>
xxxx
</div>
</div>
</div>
</a>
</div>
</div>
</div>
I have another index page with the exact same layout and the link renders as expected (one tag surrounding the card). This is why I am expecting my code above for my shipments index page to work exactly the same, but I can't figure out why it does not.
Here is the code for the index page with the link_to that works as expected:
<%= render Atoms::PageLayoutComponent.new(header: "Find a rule/regulation") do |page_layout| %>
<% page_layout.with_page_content do %>
<%= render Ui::ShipmentRules::ShipmentRulesFiltersComponent.new(shipment_rules: @shipment_rules) %>
<%= turbo_frame_tag "reseller_shipment_rules_results" do %>
<div class="grid gap-3">
<div>Recently updated rules</div>
<% @shipment_rules.each do |shipment_rule| %>
<%= link_to reseller_shipment_rule_path(shipment_rule), data: { turbo_frame: "_top" } do %>
<%= render Ui::ShipmentRules::ShipmentRuleComponent.new(shipment_rule:) %>
<% end %>
<% end %>
</div>
<% end %>
<div class="grid place-content-center">
<%== pagy_nav(@pagy) %>
</div>
<% end %>
<% end %>
I realised what caused the strange behaviour. I have a nested <a>
tag in the child component (ShipmentComponent) which is actually forbidden. Nesting <a>
elements is not valid HTML, so the browser was trying to "correct" the code.