Partial reloads vs. full visits for paginated Inertia tables when SEO and history matter
0 reputation · 09 Jan 2022, 13:53 UTC
0 reputation · 09 Jan 2022, 13:53 UTC
An Inertia.js application renders a large dataset using Laravel's LengthAwarePaginator serialized into Inertia's pagination object. The product team requires indexable URLs for each page (e.g., /posts?page=3) and browser history support so users can navigate back to a specific page. At the same time, the UX goal is to avoid full-page flashes when moving between pages.
The pagination mechanism must preserve a shareable, crawlable URL per page and maintain history entries, while minimizing perceived latency during page changes.
Two documented patterns are available:
router.visit(url) or router.get(url)) update the URL, push history, and are SEO-friendly by default, but trigger a complete page replacement including re-mounting components.router.reload({ only: ['posts'] })) fetch only the paginated prop, keeping the component mounted and avoiding a flash, but they do not update the browser URL or history stack unless manually augmented.Both approaches can return the same paginated JSON structure from the backend.
history.pushState call to sync the URL?preserveScroll option (or a custom scroll restoration strategy) behave differently between these two approaches when the component stays mounted versus re-mounting?35775 reputation · 10 Jan 2022, 01:04 UTC
When SEO and deep-linking are hard requirements, the accepted architectural pattern is to use full Inertia visits (router.get). While partial reloads offer a smoother UX by avoiding component re-mounting, they fail the fundamental requirement of providing a unique, history-backed URL that is crawlable and shareable.
In Inertia, a standard visit via router.get('/posts?page=3') ensures that the browser's history stack is updated and the URL reflects the current state. This is critical because search engine crawlers navigate and index unique pages. If the URL does not change during a partial reload, the crawler will only see the first page of your dataset.
The 're-mount cost' is often overestimated. The actual performance impact depends on the complexity of your page layout. If the table is part of a larger page, Inertia's efficient diffing of props minimizes the DOM work, but the component will technically re-initialize.
If you attempt to combine partial reloads (router.reload({ only: ['posts'] })) with manual history.pushState, you introduce significant edge cases:
preserveScroll option is designed to work with the visit lifecycle. Manual state manipulation bypasses Inertia's internal scroll logic, often resulting in the page jumping to the top unexpectedly.Scroll restoration behaves differently significantly between the two:
preserveScroll: true, Inertia records the scroll position before the visit and restores it after the new component is mounted. This is highly reliable for table navigation.To balance UX and SEO requirements, follow this implementation path:
&Link; components for pagination to ensure unique URLs and history entries.preserveScroll: true on the pagination links to prevent the page from jumping.Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 09 Jan 2022, 20:14 UTC
To further clarify the trade-off between full visits and partial reloads, it is important to note how preserveState interacts with these patterns. While router.get() typically triggers a component re-mount, using preserveState: true can prevent the component from resetting its internal state during the visit.
When implementing these patterns, you can verify the behavior using these steps:
/posts?page=3) in a browser with JavaScript disabled. If the server returns the correct HTML for that page, the full-visit approach is SEO-compliant.router.get requests include the X-Inertia header and that the popstate event correctly triggers a data fetch when the back button is pressed.Relying on preserveState with full visits often provides the "smooth" feel of a partial reload while maintaining the robust history and SEO benefits of a standard Inertia visit.