# Client-side context with the Next.js App Router SDK

> Use the Uniform Context in the browser with the Next.js App Router SDK: hooks and a custom client context.

Source: https://docs.uniform.app/docs/sdk/nextjs-app-router/client-context

> **Developer Preview:**
>
> This page documents the developer preview of the SDK, version `20.81.1-alpha.25.sha-f076f9b857`.

Most Uniform components render on the server and do not use JavaScript in the browser. These tasks use the browser Context:

- Read or update the quirks of the visitor
- Read the scores of the visitor
- Update the page when the Context changes

> **Warning:**
>
> Put `"use client"` at the top of the file of a component that uses `useUniformContext`, `useQuirks`, `useScores` or a browser API. This is a rule of React Server Components.
>
> Keep client components small, and put them low in the component tree. `"use client"` makes the component and all its children client components. Then more JavaScript goes to the browser. For example, put only the button that updates a quirk in a client component, not the full page.

## useUniformContext

`useUniformContext` gives the Uniform Context instance in the browser:

```tsx
"use client";

import { useUniformContext } from "@uniformdev/next-app-router/component";

export const QuirkButton = () => {
  const { context } = useUniformContext();

  return (
    <button
      disabled={!context}
      onClick={() => context?.update({ quirks: { country: "Canada" } })}
    >
      Set the country to Canada
    </button>
  );
};
```

> **Note:**
>
> `context` is `undefined` until the browser Context is ready. Always check for `undefined`.

## useQuirks

`useQuirks` returns the quirks of the visitor. The component renders again when the quirks change:

```tsx
"use client";

import { useQuirks } from "@uniformdev/next-app-router/component";

export const LocationBanner = () => {
  const quirks = useQuirks();
  return <div>Country: {quirks?.country ?? "Unknown"}</div>;
};
```

## useScores

`useScores` returns the scores of the visitor. The component renders again when the scores change:

```tsx
"use client";

import { useScores } from "@uniformdev/next-app-router/component";

export const InterestIndicator = () => {
  const scores = useScores();
  return <div>Tech interest score: {scores?.tech ?? 0}</div>;
};
```

## Custom client context

A custom client context lets you add Context plugins, for example analytics, or change the dev tools. Install `@uniformdev/context`, then make the component:

`components/CustomUniformClientContext.tsx`

```tsx
"use client";

import { type ContextPlugin, enableContextDevTools } from "@uniformdev/context";
import {
  type ClientContextComponent,
  createClientUniformContext,
  useInitUniformContext,
} from "@uniformdev/next-app-router/component";
import { useRouter } from "next/navigation";

export const CustomUniformClientContext: ClientContextComponent = ({
  manifest,
  disableDevTools,
  defaultConsent,
  experimentalQuirkSerialization,
  compositionMetadata,
}) => {
  const router = useRouter();

  useInitUniformContext(() => {
    const plugins: ContextPlugin[] = [];

    if (!disableDevTools) {
      plugins.push(enableContextDevTools({ onAfterMessageReceived: () => router.refresh() }));
    }

    return createClientUniformContext({
      manifest,
      plugins,
      defaultConsent,
      experimental_quirksEnabled: experimentalQuirkSerialization,
    });
  }, compositionMetadata);

  return null;
};
```

Give it to `UniformComposition` (and to `UniformPlayground`, if you want it there too):

```tsx
<UniformComposition
  code={code}
  resolveComponent={resolveComponent}
  clientContextComponent={CustomUniformClientContext}
/>
```

`useInitUniformContext` makes the Context one time in the browser. On each client-side navigation, it updates the Context with the new URL and the quirks from the middleware.
