В Build UI рассказали, как можно создать прогресс загрузки страницы с помощью Transition API. В результате получился хук useProgress и компоненты прогресса с Framer Motion:
const { start, done, reset, state, value } = useProgress();
Чтобы показать прогресс загрузки страницы в Next.js, то необходимо использовать Transition API. Пример:
const router = useRouter();
const { start, done } = useProgress();
return (
<Link
onClick={(e) => {
e.preventDefault();
start();
startTransition(() => {
router.push(href);
done();
});
}}
href={href}
>
{children}
</Link>
);
В Next.js router.push не возвращает промис, но использует Transition API. React вызывает все обновления стейта внутри startTransition одновременно в фоне. Если какое-то обновление будет приостановлено, в нашем случае так делает router.push, то React отложит отрисовку UI, пока все обновления не будут завершены.
Можно считать, что вызов startTransition создает форк текущего дерева и применяет все обновления на этом дереве. После того, как все обновления завершены, новое дерево отрисовывается в DOM.
https://buildui.com/posts/global-progress-in-nextjs