Using Next.js as a single-page app (SPA) comes with many benefits but has a major downside: stale sessions. Because users never need to refresh the page, they can go days or weeks without doing so. This makes evolving your API much more difficult. Fully deprecating an endpoint can take weeks or even months.
A common pattern to solve this problem is prompting users to refresh:
To our surprise, there wasn’t a drop-in way to do this in Next.js. They offer some mechanisms to trigger a refresh upon page navigation, but this can be jarring for users without warning. To fill this gap, we’re sharing how we solved this problem.
We have the Next.js server track its current version number. Then the front-end track its own version and polls the Next.js server for the latest version number. When these versions differ, prompt the user to refresh.
// pages/api/requires-refresh/[version].ts
export const LATEST_APP_VERSION = 105;
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<boolean>
) {
const requestVersion = parseInt(req.query.version);
const needsRefresh = requestVersion < LATEST_APP_VERSION;
res.status(200).json(needsRefresh);
}
import { LATEST_APP_VERSION as versionOnLoad } from "./api/requires-refresh/[version]";
const RefreshChecker = () => {
const [showRefreshPrompt, setShowRefreshPrompt] = React.useState(false);
React.useEffect(() => {
async function checkRefresh() {
const url = "/api/requires-refresh/" + versionOnLoad;
const res = await fetch(url);
if (res.ok) {
const needsRefresh = await res.json();
if (needsRefresh) {
setShowRefreshPrompt(true);
}
}
}
const id = setInterval(checkRefresh, 60_000);
return () => clearInterval(id);
}, []);
if (showRefreshPrompt) {
// Render your refresh prompt here
return <div>Refresh required</div>;
} else {
return null;
}
};
This approach works great for allowing engineers to prompt user refreshes when needed by changing a single line of code. It’s simple and works out of the box with Next.js. By sharing our approach, we hope to help other teams who face similar challenges.
At Comulate, we’re building a product-obsessed engineering team. If this and similar challenges sound interesting, we’d love to chat! See open roles here.