# Query evaluation

Learn how to evaluate CQL queries to personalize and segment your storefront.

Croct lets you evaluate [CQL](/reference/cql) queries to personalize and segment your visitors. You can evaluate on the server in your loaders for flicker-free rendering, or on the client with a hook.

## Server-side evaluation \[#basic-usage]

[Evaluate a query](/reference/sdk/hydrogen/api/functions/evaluate) from a loader with the loader's context, then render from the result:

**React Router 7 — JavaScript**

```jsx
import {useLoaderData} from 'react-router';
import {evaluate} from '@croct/plug-hydrogen/server';

export async function loader({context}) {
  const country = await evaluate("location's country", {
    scope: context,
  });

  return {country: country};
}

export default function Index() {
  const {country} = useLoaderData();

  return <p>Hello from {country ?? 'somewhere'}!</p>;
}
```

**React Router 7 — TypeScript**

```tsx
import {useLoaderData} from 'react-router';
import {evaluate} from '@croct/plug-hydrogen/server';
import type {Route} from './+types/_index';

export async function loader({context}: Route.LoaderArgs) {
  const country = await evaluate<string | null>("location's country", {
    scope: context,
  });

  return {country: country};
}

export default function Index() {
  const {country} = useLoaderData<typeof loader>();

  return <p>Hello from {country ?? 'somewhere'}!</p>;
}
```

**Remix — JavaScript**

```jsx
import {useLoaderData} from '@remix-run/react';
import {evaluate} from '@croct/plug-hydrogen/server';

export async function loader({context}) {
  const country = await evaluate("location's country", {
    scope: context,
  });

  return {country: country};
}

export default function Index() {
  const {country} = useLoaderData();

  return <p>Hello from {country ?? 'somewhere'}!</p>;
}
```

**Remix — TypeScript**

```tsx
import {useLoaderData} from '@remix-run/react';
import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {evaluate} from '@croct/plug-hydrogen/server';

export async function loader({context}: LoaderFunctionArgs) {
  const country = await evaluate<string | null>("location's country", {
    scope: context,
  });

  return {country: country};
}

export default function Index() {
  const {country} = useLoaderData<typeof loader>();

  return <p>Hello from {country ?? 'somewhere'}!</p>;
}
```

## Client-side evaluation

To evaluate a query in a component, use the [evaluation hook](/reference/sdk/hydrogen/api/hooks/use-evaluation):

**JavaScript**

```jsx
import {useEvaluation} from '@croct/plug-hydrogen';

export function CountryGreeting() {
  const country = useEvaluation("location's country", {
    initial: null,
  });

  return <p>Hello from {country ?? 'somewhere'}!</p>;
}
```

**TypeScript**

```tsx
import type {ReactElement} from 'react';
import {useEvaluation} from '@croct/plug-hydrogen';

export function CountryGreeting(): ReactElement {
  const country = useEvaluation<string | null>("location's country", {
    initial: null,
  });

  return <p>Hello from {country ?? 'somewhere'}!</p>;
}
```

## Context variables

Add custom attributes to the [evaluation context](/reference/sdk/hydrogen/api/functions/evaluate#options-context-prop) to enrich it with application-specific information. These values are accessible in the [context variable](/reference/cql/context#evaluation):

**JavaScript**

```jsx
import {evaluate} from '@croct/plug-hydrogen/server';

export async function loader({context}) {
  const isPremium = await evaluate("context's plan is 'premium'", {
    scope: context,
    context: {
      attributes: {
        plan: 'premium',
      },
    },
  });

  return {isPremium: isPremium};
}
```

**TypeScript**

```tsx
import {evaluate} from '@croct/plug-hydrogen/server';
import type {Route} from './+types/_index';

export async function loader({context}: Route.LoaderArgs) {
  const isPremium = await evaluate<boolean>("context's plan is 'premium'", {
    scope: context,
    context: {
      attributes: {
        plan: 'premium',
      },
    },
  });

  return {isPremium: isPremium};
}
```

## Fault tolerance

> **Good to know**
>
> Always provide a fallback so that evaluation failures, such as network errors or timeouts, degrade gracefully instead of breaking the page.

Specify the value to return when the evaluation cannot complete:

**JavaScript**

```jsx
import {evaluate} from '@croct/plug-hydrogen/server';

export async function loader({context}) {
  const country = await evaluate("location's country", {
    scope: context,
    fallback: null,
  });

  return {country: country};
}
```

**TypeScript**

```tsx
import {evaluate} from '@croct/plug-hydrogen/server';
import type {Route} from './+types/_index';

export async function loader({context}: Route.LoaderArgs) {
  const country = await evaluate<string | null>("location's country", {
    scope: context,
    fallback: null,
  });

  return {country: country};
}
```

## Explore

- [evaluate](api/functions/evaluate): Explore the evaluate function and its options.
- [CQL](/reference/cql): Learn the contextual query language used to personalize content.
