1

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 %> 
1
  • We are unaware of the content of the 2 view components posted. Are you sure they are not generating the nested links? Commented Apr 10, 2024 at 15:08

2 Answers 2

1

It looks like you're using ViewComponents. I believe you can fix this using the capture compatibility patch.

Create the file config/initializers/view_component.rb with the following contents and restart your server:

Rails.application.configure do config.view_component.capture_compatibility_patch_enabled = true end 

(You could also stick this in your environment config)

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.