How to display loading.tsx during app router navigation
Unanswered
Matt posted this in #help-forum
MattOP
I have a shared layout with each page having a loading.tsx. I see the loading.tsx during the initial load of the page. I would expect to also see the loading.tsx during navigation with <Link /> but it seems like it waits for the rsc payload to start streaming before fully navigating with no loading shown.
My ideal behavior is the user immediately sees feedback that we're fetching the next page (loading.tsx or equivalent), because on slow networks it's not clear if your tap went through or that we're actually doing anything.
I'm having trouble wrapping my head around this and would love thoughts from others.
My ideal behavior is the user immediately sees feedback that we're fetching the next page (loading.tsx or equivalent), because on slow networks it's not clear if your tap went through or that we're actually doing anything.
I'm having trouble wrapping my head around this and would love thoughts from others.
2 Replies
Giant panda
The nextjs is preloading data while the user is waiting and the loading file is not used in this stage. If you want to implement what you said you have to first change the state of the parent to loading and then immediately tell nextjs to navigate. This way the user sees loading while nextjs is preloading and then navigate
Simple example
// notice that the loading is preferably from a parent
import { useRouter } from 'next/router';
import { useState } from 'react';
function MyLinkComponent({ href, children }) {
const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const handleClick = (e) => {
e.preventDefault();
setIsLoading(true);
router.push(href).then(() => {
setIsLoading(false);
});
};
return (
#Unknown Channel
<a href={href} onClick={handleClick}>
{children}
</a>
{isLoading && <div>Loading...</div>}
</>
);
}
Simple example
// notice that the loading is preferably from a parent
import { useRouter } from 'next/router';
import { useState } from 'react';
function MyLinkComponent({ href, children }) {
const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const handleClick = (e) => {
e.preventDefault();
setIsLoading(true);
router.push(href).then(() => {
setIsLoading(false);
});
};
return (
#Unknown Channel
<a href={href} onClick={handleClick}>
{children}
</a>
{isLoading && <div>Loading...</div>}
</>
);
}
MattOP
that doesn't seem right... bypassing Link gets rid of prefetching etc.. I'm really surprised there's no way to have Link display instant feedback...