Next.js Integration
Integrate RuntimeHQ into Next.js App Router using Server and Client Components
Next.js Integration
RuntimeHQ integrates seamlessly into Next.js App Router applications. Because Next.js blends server rendering with client interactivity, RuntimeHQ leverages both core SDKs:
- Server Components & Route Handlers: Use
@theruntimehq/jsfor pre-rendering, server-side redirects, and outage gating before HTML is delivered to the browser. - Client Components: Use
@theruntimehq/reactfor real-time background polling, dynamic UI degradation, and interactive component state.
Like all RuntimeHQ SDKs, this integration is pure state management—there are no UI components, CSS styles, or external state dependencies.
Installation
Install both the core JavaScript SDK and the React SDK:
npm install @theruntimehq/js @theruntimehq/reactValidate After Installation
After installing and setting up the SDK, validate your integration using Non-Production Simulation. Simulation allows you to safely test state changes, UI fallbacks, and capability degradation during peacetime using your non-production key (rt_test_...) without impacting production traffic.
Environment Keys
RuntimeHQ runtime keys start with rt_prod_ or rt_test_. They are public, read-only status keys.
Add them to your .env.local or deployment environment variables:
# Server-side operations (Server Components, Route Handlers, Middleware)
RUNTIMEHQ_KEY=rt_prod_xxxxx
# Client-side operations (Client Components, Provider)
NEXT_PUBLIC_RUNTIMEHQ_KEY=rt_prod_xxxxxSee Runtime Keys for key management and environment separation.
Architecture & Patterns
1. Server Components (SSR & Outage Gating)
For server rendering and SEO protection, fetch the runtime state on the server using @theruntimehq/js. This intercepts outages and degraded states securely before the page is ever delivered to the browser, completely avoiding layout shifts or flash-of-degraded-content.
// app/transfers/page.tsx
import { RuntimeHQClient } from "@theruntimehq/js";
import { redirect } from "next/navigation";
import TransferForm from "./TransferForm";
const client = new RuntimeHQClient({
runtimeKey: process.env.RUNTIMEHQ_KEY!
});
export default async function TransfersPage() {
const runtime = await client.getRuntime();
const transfersCapability = runtime.getCapabilityState("transfers");
// Intercept outages server-side and redirect or render a maintenance view
if (transfersCapability?.state === "OUTAGE") {
redirect(`/outage?message=${encodeURIComponent(transfersCapability.message)}`);
}
return (
<main className="container mx-auto py-8">
<h1 className="text-2xl font-bold">Transfer Funds</h1>
{/* Client Component for interactive submission */}
<TransferForm />
</main>
);
}Server Request Deduplication
If multiple Server Components query runtime status during the same render pass, wrap the client call in React's cache():
// lib/runtimehq.ts
import { cache } from "react";
import { RuntimeHQClient } from "@theruntimehq/js";
const client = new RuntimeHQClient({
runtimeKey: process.env.RUNTIMEHQ_KEY!
});
export const getRuntime = cache(async () => {
return client.getRuntime();
});2. Client Components (Reactive Polling)
For interactive components that need live updates while the user is active on the page, set up the React provider in a client boundary.
Step A: Create a Client Providers Wrapper
Create an app/providers.tsx file marked with "use client":
// app/providers.tsx
"use client";
import { RuntimeHQProvider } from "@theruntimehq/react";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<RuntimeHQProvider
runtimeKey={process.env.NEXT_PUBLIC_RUNTIMEHQ_KEY!}
intervalSeconds={60}
>
{children}
</RuntimeHQProvider>
);
}Step B: Wrap Root Layout
Wrap your application in app/layout.tsx. The layout remains a Server Component:
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}Step C: Consume in Client Components
Use useRuntimeHQ in any client component to reactively handle state changes:
// app/transfers/TransferForm.tsx
"use client";
import { useRuntimeHQ, isOutage, isDegraded } from "@theruntimehq/react";
export default function TransferForm() {
const { getCapabilityState } = useRuntimeHQ();
const transfers = getCapabilityState("transfers");
const isDown = isOutage(transfers);
const isSlow = isDegraded(transfers);
return (
<form className="space-y-4">
{isSlow && (
<div className="alert alert-warning">
Transfers are experiencing delays. {transfers?.message}
</div>
)}
<button
type="submit"
disabled={isDown}
className="btn btn-primary"
>
{isDown ? "Transfers Unavailable" : "Submit Transfer"}
</button>
</form>
);
}Validating the Integration
Validate your Next.js application's resilience during peacetime using Non-Production Simulation:
- Configure Non-Production Key: Set
NEXT_PUBLIC_RUNTIMEHQ_KEY=rt_test_...andRUNTIMEHQ_KEY=rt_test_...in your.env.localor preview environments. - Trigger Simulation: In the RuntimeHQ Console, open your application's Non-Production Simulation State panel. Select an affected state (e.g.,
DEGRADEDorOUTAGE) and target capabilities (e.g.,transfers). - Verify Server & Client Paths:
- Navigate to
/transfersto verify server-side redirection. - Test in-page client behavior while adjusting simulation states in real time.
- Navigate to
- Reset: Clear the simulation in the Console to return staging to baseline operational state.
Links & Resources: