Skip to content

Conversation

@sahitya-chandra
Copy link

@sahitya-chandra sahitya-chandra commented Feb 1, 2026

Issue: #3061 (Parent: #3028)
closes: #3061

Description

Migrates product pages from React on Rails / ERB to Inertia by rendering a different Inertia page per layout

Problem

  • Product pages were still rendered via ERB in app/views/links/show.html.erb with conditional react_component calls (ProductPage, ProfileProductPage, DiscoverProductPage, ProductIframePage) based on params[:layout], params[:embed], and params[:overlay].
  • This did not follow the Inertia migration pattern used elsewhere and did not meet the goal of “render a different Inertia page for each layout” (sub-issue Migrate Product Pages to Inertia #3061).

Solution

  • Controller: LinksController#show now uses Inertia for all HTML responses:
    • Links/Show (default product page)
    • Links/Profile when params[:layout] == "profile"
    • Links/Discover when params[:layout] == "discover"
    • Links/Iframe when params[:embed] or params[:overlay]
  • Layout: Product pages use the inertia layout by adding :show to layout "inertia", only: [...].
  • Sidebar: Pass hide_layouts: true in product page props and extend the shared Inertia layout to respect hide_layouts so the dashboard Nav is not rendered on product pages.
  • Templates: New Inertia pages under app/javascript/pages/Links/ (Show, Profile, Discover, Iframe) that use the existing Product/Profile/Discover/Iframe layout components.
  • Cleanup: Remove app/views/links/show.html.erb and the React-on-Rails product page components from app/javascript/packs/product.ts and app/javascript/ssr.ts.
  • Pack loading: In application and inertia layouts, load the base pack when inertia_rendering? || !@hide_layouts so product Inertia pages still load the app.
  • Specs: Update spec/controllers/links_controller_spec.rb for the new Inertia behavior.

Before/After

Before: Product page was rendered by ERB and React on Rails (conditional react_component for ProductPage, ProfileProductPage, DiscoverProductPage, ProductIframePage).

Screencast.from.2026-02-02.03-04-39.webm

After: Product page is rendered by Inertia (Links/Show, Links/Profile, Links/Discover, Links/Iframe) with the same UI;

Screencast.from.2026-02-02.03-09-57.webm

Test Results

bundle exec rspec spec/controllers/links_controller_spec.rb:3210 spec/controllers/links_controller_spec.rb:3217 spec/controllers/links_controller_spec.rb:3224 spec/controllers/links_controller_spec.rb:3231 spec/controllers/links_controller_spec.rb:3238
Screenshot from 2026-02-02 03-20-59

Checklist


AI Disclosure

  • used cursor with opus-4.5 to plan the solution and refactoring code

before_action :fetch_product_and_enforce_access, only: %i[update publish unpublish release_preorder update_sections]

layout "inertia", only: [:index, :new, :cart_items_count]
layout "inertia", only: [:index, :new, :cart_items_count, :show]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Product pages are now Inertia pages, so they use the same inertia layout as other Inertia actions (index, new, cart_items_count). That way /l/:id gets the inertia layout and the base pack loads correctly. Without :show, product pages would use the default application layout and the Inertia app wouldn’t mount.

Comment on lines +165 to +176
format.html do
product_page_props = @product_props.merge(hide_layouts: true)
if params[:layout] == "profile"
render inertia: "Links/Profile", props: product_page_props.merge({
creator_profile: ProfilePresenter.new(pundit_user:, seller: @product.user).creator_profile
})
elsif params[:layout] == Product::Layout::DISCOVER
render inertia: "Links/Discover", props: product_page_props.merge(@discover_props)
elsif params[:embed] || params[:overlay]
render inertia: "Links/Iframe", props: product_page_props
else
render inertia: "Links/Show", props: product_page_props
Copy link
Author

@sahitya-chandra sahitya-chandra Feb 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now render a different Inertia page per layout (Links/Show, Profile, Discover, Iframe) instead of ERB + React-on-Rails. We merge hide_layouts: true into product props so the shared Layout can hide the Nav

Comment on lines +32 to +36
hide_layouts?: boolean;
};

export default function Layout({ children }: { children: React.ReactNode }) {
const { flash, logged_in_user, current_seller } = usePage<PageProps>().props;
const { flash, logged_in_user, current_seller, hide_layouts } = usePage<PageProps>().props;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We read hide_layouts from page props and only render the Nav when logged_in_user && !hide_layouts. Product pages pass hide_layouts: true, so they get the same Layout (and providers) but no sidebar.

</div>
<%= javascript_include_tag "application" %>
<%= load_pack("base") unless @hide_layouts %>
<%= load_pack("base") if inertia_rendering? || !@hide_layouts %>
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We changed to load_pack("base") if inertia_rendering? || !@hide_layouts so the base pack (Inertia app) loads on product pages too. On main, base wasn’t loaded when @hide_layouts was true; now it must be when the response is Inertia, or the product page wouldn’t hydrate.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProductPage, ProfileProductPage, DiscoverProductPage, and ProductIframePage are removed; product pages are now Inertia (Links/Show, etc.). ProfileCoffeePage stays for the coffee profile React-on-Rails page.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Links/Show, Profile, Discover, and Iframe are thin Inertia pages that delegate to the existing Product/Profile/Discover/Iframe layout components. They use the default Inertia layout (with hide_layouts hiding the Nav), not layout = false.

Copy link
Author

@sahitya-chandra sahitya-chandra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self review

@sahitya-chandra
Copy link
Author

@Pradumn27 _a sir, can you give an initial review of this pr?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate Product Pages to Inertia

2 participants