Redirect Engine (redirect.jsx / client-redirect.jsx)
Examine the server HTTP redirection handler, client SPA router interceptors, and React Suspense render block triggers.
Key Files Location:
• Server Redirect:./dinou/core/redirect.jsx
• Client Redirect:./dinou/core/client-redirect.jsx
💡 Overview
Redirecting users is an essential feature of routing systems. In hybrid architectures (combining Server Components and Single Page Application clients), redirection must be handled at both levels:
- On the Server: If the user performs a hard load (e.g. hitting an authorized URL without log cookies), the server should return a native
302/307 Redirectheader instantly. - During Hydration or Navigation: If a component redirects dynamically after headers have been sent, the framework must trigger client-side SPA routing without reloading the browser.
📊 Redirect Engine Flow
The flowchart below traces the redirect resolution checks from server context detection to client suspense interception:
⚡ React Suspense Redirects
A challenge in client-side redirections is preventing React from committing a half-rendered, broken page layout during the route swap.
Dinou solves this using **React Suspense Interception**:
- Queue Router Task: Invokes
router.replace(to)inside a microtask (Promise.resolve().then(...)) to trigger client-side navigation. - Suspend Render: Immediately executes
throw new Promise(() => ). Because a pending promise is thrown, React suspends rendering of this branch. - Page Transition: React stops rendering the current route and waits. The queued microtask fires, changing the router state and mounting the target page cleanly without displaying layout flicker.
⚙️ Server Code (redirect.jsx)
Below is the code for the server-side orchestrator redirect.jsx:
import { ClientRedirect } from "./client-redirect.jsx";
/**
* Universal redirection function.
* Use it with 'return': return redirect('/login');
*/
export function redirect(destination) {
// 1. If executing on the Server-side
if (typeof window === "undefined") {
const dynamicRequire =
typeof __dinou_require__ !== "undefined"
? __dinou_require__
: typeof module !== "undefined" && typeof module.require === "function"
? module.require.bind(module)
: null;
if (dynamicRequire) {
const { getContext } = dynamicRequire("./request-context.js");
const ctx = getContext();
// 2. If HTTP headers have NOT been sent yet, trigger a native 302/307 redirect.
// This is optimal for SEO crawls and hard navigations.
if (ctx && ctx.res) {
ctx.res.redirect(destination);
return <ClientRedirect to={destination} />;
}
}
}
// 3. Fallback: If headers are already sent, or if executing on the client,
// return the ClientRedirect component.
return <ClientRedirect to={destination} />;
}⚙️ Client Code (client-redirect.jsx)
Below is the code for the client-side component client-redirect.jsx:
// dinou/core/client-redirect.jsx
"use client";
import { useRouter } from "./navigation.js";
export function ClientRedirect({ to }) {
const router = useRouter();
if (typeof window !== "undefined") {
// 1. Queue navigation task in a microtask
Promise.resolve().then(() => {
if (window.__DINOU_ROUTER_NAVIGATE__) {
window.__DINOU_ROUTER_NAVIGATE__(to, { replace: true });
} else {
router.replace(to);
}
});
// 2. Suspends React to prevent rendering intermediate stale page states
throw new Promise(() => {});
}
return null;
}