-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Shallow Routing (from Next.js) #2673
Comments
Also related: #2301 |
Wouldn't it be a conceptually simpler model to put your tree data in a store, and have each |
I guess the problem is that, after |
Your To avoid |
As mentioned in #969 (comment), one use case for this could be updating query parameters without causing navigation (which has unwanted side-effects). |
This comment was marked as off-topic.
This comment was marked as off-topic.
doesn't |
Most, but it causes |
Some thoughts: This could be a new option on The alternative would be some kind of I'm not sure which solution would be more viable in practice. The first option has more flexibility, but do people need that flexibility? |
I'm not sure Three use cases:
I'm not pretending to have figured out all the details, but here are some high-level thoughts: In all these cases, we're using For the sake of argument, let's call that new function Usage: <script>
import { pushState } from '$app/navigation';
import { page } from '$app/stores';
</script>
<button on:click={() => pushState('.', { modal: true })>
show modal
</button>
{#if $page.state?.modal}
<div class="modal">...</div>
{/if} {#each photos as photo}
<a
href="/p/{photo.id}
on:click|preventDefault={() => {
pushState(`/p/${photo.id}`, {
photo
});
}}
>
<img alt={photo.alt} src={photo.thumbnail}>
</a>
{/each}
{#if $page.state?.photo}
<div class="expanded">
<img alt={$page.state.photo.alt} src={$page.state.photo.src}>
</div>
{/if} We probably also want to call |
I can think of cases where one could want to update the client url's search params but without running any |
If we were to call |
I don't think we can get away with just one opionated function for this: Conflicting opinions/needs regarding to history:
Conflicting opinions/needs regarding
Conflicting opinions/needs regarding
Conflicting opinions regarding
Furthermore, a new function that is almost
(I would be ok with a helper function that wraps Looking at the example code Rich gave, I'm not even sure why |
I read through some of the use cases in this issue and #969, and I agree with @Rich-Harris that the common use case seems to be changing the URL without triggering navigation. Here's what I observe in most1 use cases:
It seems to me that what we're really trying to achieve is that changes to certain parts of the URL shouldn't trigger a navigation, regardless of how that URL change was triggered in the first place ( I can almost achieve this behavior using a check in
I'm not sure if adding an option to Footnotes
|
I don't think we can say that an intercepted navigation to If we were to treat intercepted routes as a distinct feature though, then all the cases we're discussing where you'd want to skip I actually think updating query parameters is the special case, rather than intercepted routes, because it's the one case where you want import { updateQuery } from '$app/navigation';
function search(q) {
updateQuery({ q });
// if it takes the same argument as URLSearchParams these would also work
updateQuery(`q=${q}`);
const params = new URLSearchParams();
params.set('q', q);
updateQuery(params);
} |
(One thing I will say for boob syntax, even though I lean in the other direction, is that it would make code-splitting easier — too finicky to avoid eagerly loading the full |
It's definitely a common one, but it's not the only case so I'd suggest not limiting the developer to only query params. I've had occasion in the past to use Next.js shallow routing for something like |
@iansinnott how did you handle the loading part of I also think special-casing this to query params is too limited. It will expand the API surface with another method that will not suffice, so we need to expand the API some more afterwards. Something like |
In the Instagram navigation case you're not skipping load, you're skipping navigation. The 'background' of the page remains the same, which means The modal case is identical to the Instagram case, except that the URL doesn't change. So I'd strongly argue that In fact the only time @iansinnott can you describe exactly what should happen when you go from |
You don't need any new API for this at all then, you can solve it through calling <script>
let open = false;
</script>
<img src=".." on:click={() => { open = true; history.pushState('/photos/id'); } />
{#if open}
<div class="modal">...</div>
{/if}
... which would be solved through |
Not exactly — you also need to create a I can't think of a situation where you'd want to reset scroll or focus — those are things that happen when you navigate. So it's really just import { goto, pushState, replaceState, updateQuery } from '$app/navigation';
pushState({ photo }, `/p/${photo.id}`);
pushState({ modal: true });
replaceState({ selected });
updateQuery({ q }); Having functions with clear nomenclature and purpose feels much nicer than making the already-convoluted |
What's the difference between |
Coming back to the instagram-photo case - following idea:
<!-- /photo/+page.svelte -->
<a href="/photo/1" data-sveltekit-intercept="photo">
<img src=".." />
</a>
{#if !$page.url.pathname.endsWith('/photo')}
<Modal>
<slot name="photo" />
<Modal>
{/if}
<!-- or, if you move the modal logic into the page, just -->
<slot name="photo" /> // photos/[photo]/+page.js
export async function load({ embedded, fetch, params }) {
const details = await fetch(`photostuff/${params.photo}`);
return {
embedded,
details: await details.json()
}
} <!-- photos/[photo]/+page.svelte -->
<script>
export let data;
</script>
{#if !data.embedded}
<h1>Details for photo {data.details.name}</h1>
{/if}
... Advantages:
TODO/drawbacks:
This all is closely related to #9625, maybe more than the simple shallow routing case? |
I think the declarative idea ( For everyone following this thread: I've implemented |
One things that's annoying and surprising/hard to keep track of with this approach of |
Describe the problem
See: https://nextjs.org/docs/routing/shallow-routing
Describe the proposed solution
plus
These would update the
page
store, butload
would not run. (Only ifhref
does not link to a new page)Alternatives considered
Using the History API directly:
But doing this does not update the
page
store (and it's ugly).Importance
would make my life easier
Additional Information
I have this
OrgTree
component which lazy loads it's items as you expand the groups:When you click an item the URI is updated using shallow routing, leaving all the loaded tree data intact.
Using Svelte Kit,
load
fetches the initial tree data, but, after navigating, the initial data is loaded again, reseting the whole tree.Related issues: #1930, #969
The text was updated successfully, but these errors were encountered: