Defer showing page with streaming + client side navigation #1667
Replies: 3 comments 5 replies
-
Indeed React has some neat transition APIs. Contribution welcome to experiment with these. Moving to discussions because so far I don't see any blocker on Vike's side.
You can already do that with
We can start experimenting on the user land (e.g. on On my side, I'm busy with That said, I'm very much looking forward to further improve this. |
Beta Was this translation helpful? Give feedback.
-
I was able to achieve this effect with //+loading.js
export default function Loading() {
// Or a custom loading skeleton component
return <p>Loading...</p>
} export { PageShell }
import React, { Suspense, useEffect, useTransition } from 'react'
import PropTypes from 'prop-types'
import { childrenPropType } from './PropTypeValues'
import logoUrl from './logo.svg'
import { PageContextProvider } from './usePageContext'
import { Link } from './Link'
import './css/index.css'
import './PageShell.css'
import { useState } from 'react';
import NProgress from "nprogress";
import 'nprogress/nprogress.css';
PageShell.propTypes = {
pageContext: PropTypes.any,
children: childrenPropType
}
function PageShell(props) {
const [stateProps, setStateProps] = useState(props);
const {
pageContext,
children
} = stateProps;
const [isPending, startTransition] = useTransition();
useEffect(() => {
startTransition(() => {
setStateProps(props);
});
}, [props]);
useEffect(() => {
if (!isPending) {
NProgress.done();
}
}, [isPending]);
const SuspenseWrapper = ({ children }) => {
return (
<Suspense
fallback={loading?.()}
>{children}</Suspense>
)
}
const PassThrough = ({ children }) => {
return (
<>{children}</>
)
}
const SuspenseConditional = loading ? SuspenseWrapper : PassThrough;
return (
<React.StrictMode>
<PageContextProvider pageContext={pageContext}>
<Layout>
<Sidebar>
<Logo />
<Link href="/">Welcome</Link>
<Link href="/about">About</Link>
<Link href="/star-wars">Data Fetching</Link>
</Sidebar>
<SuspenseConditional>
<Content>
{children}
</Content>
</SuspenseConditional>
</Layout>
</PageContextProvider>
</React.StrictMode>
)
}
Layout.propTypes = {
children: childrenPropType
}
function Layout({ children }) {
return (
<div
style={{
display: 'flex',
maxWidth: 900,
margin: 'auto'
}}
>
{children}
</div>
)
}
Sidebar.propTypes = {
children: childrenPropType
}
function Sidebar({ children }) {
return (
<div
id="sidebar"
style={{
padding: 20,
flexShrink: 0,
display: 'flex',
flexDirection: 'column',
lineHeight: '1.8em',
borderRight: '2px solid #eee'
}}
>
{children}
</div>
)
}
Content.propTypes = {
children: childrenPropType
}
function Content({ children }) {
return (
<div id="page-container">
<div
id="page-content"
style={{
padding: 20,
paddingBottom: 50,
minHeight: '100vh'
}}
>
{children}
</div>
</div>
)
}
function Logo() {
return (
<div
style={{
marginTop: 20,
marginBottom: 10
}}
>
<a href="/">
<img src={logoUrl} height={64} width={64} alt="logo" />
</a>
</div>
)
} I think in I made it in old playground created from vike template (I don't remember which exactly) so it's not cleaned up and I shared just a snippet instead of repo. |
Beta Was this translation helpful? Give feedback.
-
FYI this is the plan so far: vikejs/vike-react#117. You'll be able to opt-out from all defaults, so you can have a fully custom UX and preserve your current implementation. We are currently working on |
Beta Was this translation helpful? Give feedback.
-
Description
With streaming and client side navigation some frameworks like next.js allow to defer showing next page until its fully loaded if there is no
<Suspense>
in page component.According to https://react.dev/reference/react/Suspense
I don't really know whether this should be implemented on the internal route level, or rather as an extension e.g.
vike-react
or somehow implemented by user but I think it would be nice to have when using suspense based hooks instead of+data.js
Without streaming and with
+data.js
it is done by default, the next page is not shown until +data.js is finished (and we can use classic nprogress to display loading indicator on top of the page).Beta Was this translation helpful? Give feedback.
All reactions