Runtime SDKsNext.js

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/js for pre-rendering, server-side redirects, and outage gating before HTML is delivered to the browser.
  • Client Components: Use @theruntimehq/react for 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/react

Validate 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_xxxxx

See 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:

  1. Configure Non-Production Key: Set NEXT_PUBLIC_RUNTIMEHQ_KEY=rt_test_... and RUNTIMEHQ_KEY=rt_test_... in your .env.local or preview environments.
  2. Trigger Simulation: In the RuntimeHQ Console, open your application's Non-Production Simulation State panel. Select an affected state (e.g., DEGRADED or OUTAGE) and target capabilities (e.g., transfers).
  3. Verify Server & Client Paths:
    • Navigate to /transfers to verify server-side redirection.
    • Test in-page client behavior while adjusting simulation states in real time.
  4. Reset: Clear the simulation in the Console to return staging to baseline operational state.

Links & Resources:

On this page