# Query evaluation

Learn how to evaluate queries in real-time.

This guide provides practical examples of using the Next.js SDK to evaluate [CQL queries](/reference/cql/introduction) from your application.

## Basic usage

To evaluate queries on the server-side, you can use either the [`evaluate`](api/functions/evaluate) or [`cql`](api/functions/cql) function.

> **How about client-side rendering?**
>
> For client-side rendering, you can follow the [React examples](/reference/sdk/react/query-evaluation#basic-usage) replacing the `@croct/plug-react` imports with `@croct/plug-next`.

Here is an example:

**Basic example**

**App router — JavaScript**

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

export async function DocsLink() {
  const isDeveloper = await evaluate("user's persona is 'developer'");

  return (
    isDeveloper
      ? <a href="/docs">View docs</a>
      : <a href="/share">Share with your developer</a>
  );
}
```

**App router — TypeScript**

```tsx
import type {ReactElement} from 'react';
import {evaluate} from '@croct/plug-next/server';

export async function DocsLink(): Promise<ReactElement> {
  const isDeveloper = await evaluate<boolean>("user's persona is 'developer'");

  return (
    isDeveloper
      ? <a href="/docs">View docs</a>
      : <a href="/share">Share with your developer</a>
  );
}
```

**Page router — JavaScript**

**pages/index.jsx**

```jsx
import {evaluate} from '@croct/plug-next/server';
import {DocsLink} from '../components/DocsLink';

export const getServerSideProps = async context => ({
  props: {
    isDeveloper: await evaluate("user's persona is 'developer'", {route: context}),
  },
});

export default function DocsPage({isDeveloper}) {
  return (
    <div>
        <DocsLink isDeveloper={isDeveloper} />
    </div>
  );
}
```

**components/DocsLink.jsx**

```jsx
export function DocsLink({isDeveloper}) {
  return (
    isDeveloper
      ? <a href="/docs">View docs</a>
      : <a href="/share">Share with your developer</a>
  );
}
```

**Page router — TypeScript**

**pages/index.tsx**

```tsx
import type {ReactElement} from 'react';
import {evaluate} from '@croct/plug-next/server';
import type {GetServerSideProps} from 'next';
import {DocsLink, DocsLinkProps} from '../components/DocsLink';

type DocsPageProps = {
  isDeveloper: boolean;
};

export const getServerSideProps: GetServerSideProps<DocsPageProps> = async context => ({
  props: {
    isDeveloper: await evaluate<boolean>("user's persona is 'developer'", {route: context}),
  },
});

export default function DocsPage({isDeveloper}: DocsPageProps): ReactElement {
  return (
    <div>
      <DocsLink isDeveloper={isDeveloper} />
    </div>
  );
}
```

**components/DocsLink.tsx**

```tsx
import type {ReactElement} from 'react';

export type DocsLinkProps = {
  isDeveloper: boolean;
};

export function DocsLink({isDeveloper}: DocsLinkProps): ReactElement {
  return (
    isDeveloper
      ? <a href="/docs">View docs</a>
      : <a href="/share">Share with your developer</a>
  );
}
```

Note that the result of the evaluation is not limited to boolean values. For example, you can use the following query to find out the location from which the user is accessing your application:

**App router — JavaScript**

```jsx
import {cql} from '@croct/plug-next/server';

export async function Location() {
  const location = await cql`location`;

  return (<address>{location.cityName}, {location.stateName} - {location.countryName}</address>);
}
```

**App router — TypeScript**

```tsx
import type {ReactElement} from 'react';
import {cql} from '@croct/plug-next/server';

type Location = {
  city: string,
  state: string,
  country: string,
};

export async function Location(): Promise<ReactElement> {
  const location = await cql<Location>`location`;

  return (<address>{location.cityName}, {location.stateName} - {location.countryName}</address>);
}
```

**Page router — JavaScript**

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

export const getServerSideProps = async context => ({
  props: {
    location: await evaluate("location", {route: context}),
  },
});

export default function LocationPage({location}) {
  return (<address>{location.cityName}, {location.stateName} - {location.countryName}</address>);
}
```

**Page router — TypeScript**

```tsx
import type {ReactElement} from 'react';
import {evaluate} from '@croct/plug-next/server';
import type {GetServerSideProps} from 'next';

type Location = {
  city: string;
  state: string;
  country: string;
};

type LocationPageProps = {
  location: Location;
};

export const getServerSideProps: GetServerSideProps<LocationPageProps> = async context => ({
  props: {
    location: await evaluate<Location>("location", {route: context}),
  },
});

export default function LocationPage({location}: LocationPageProps): ReactElement {
  return (<address>{location.cityName}, {location.stateName} - {location.countryName}</address>);
}
```

In this case, the result of the evaluation is a [geographic location](/reference/cql/data-types/location/location), and the output would look like this:

**Rendered output**

```html
<address>San Francisco, California - United States</address>
```

*In the browser version of this page, this example is evaluated live for the visitor.*

By the way, the example above is personalized using the [`<Personalization>`](api/components/personalization) component directly in [MDX](https://mdxjs.com/).

## Fault tolerance

You should always provide a fallback value when evaluating queries to make your application resilient to unexpected errors, downtime, and network failures.

All you have to do is specify the result you want to use as a fallback:

**App router — JavaScript**

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

export async function Greeting() {
  const returning = await evaluate("user is returning", {fallback: false});

  return returning ? 'Welcome back!' : 'Welcome!';
}
```

**App router — TypeScript**

```tsx
import type {ReactNode} from 'react';
import {evaluate} from '@croct/plug-next/server';

export async function Greeting(): Promise<ReactNode> {
  const returning = await evaluate<boolean>("user is returning", {fallback: false});

  return returning ? 'Welcome back!' : 'Welcome!';
}
```

**Page router — JavaScript**

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

export const getServerSideProps = async context => ({
  props: {
    returning: await evaluate("user is returning", {
      route: context,
      fallback: false,
    }),
  },
});

export default function Greeting({returning}) {
  return returning ? 'Welcome back!' : 'Welcome!';
}
```

**Page router — TypeScript**

```tsx
import type {ReactNode} from 'react';
import {evaluate} from '@croct/plug-next/server';
import type {GetServerSideProps} from 'next';

type GreetingPageProps = {
  returning: boolean;
};

export const getServerSideProps: GetServerSideProps<GreetingPageProps> = async context => ({
  props: {
    returning: await evaluate<boolean>("user is returning", {
      route: context,
      fallback: false,
    }),
  },
});

export default function Greeting({returning}: GreetingPageProps): ReactNode {
  return returning ? 'Welcome back!' : 'Welcome!';
}
```

In this example, the result is set to `false` if the evaluation fails, ensuring that the application will work even if the evaluation fails.

## Context variables

In some cases, you may want to pass additional information that can be used by the query in the evaluation process.

For example, let's say you want to check whether the user is accessing your application from one of a list of countries. The SDK allows you to pass this information as an attribute to the query:

**App router — JavaScript**

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

export async function ConditionalFeature() {
  const enabled = await evaluate("context's countries include location's countryName", {
    context: {
      attributes: {
        countries: ['United States', 'Canada', 'Mexico'],
      },
    },
  });

  return enabled ? 'Available' : 'Unavailable';
}
```

**App router — TypeScript**

```tsx
import type {ReactNode} from 'react';
import {evaluate} from '@croct/plug-next/server';

export async function ConditionalFeature(): Promise<ReactNode> {
  const enabled = await evaluate<boolean>("context's countries include location's countryName", {
    context: {
      attributes: {
        countries: ['United States', 'Canada', 'Mexico'],
      },
    },
  });

  return enabled ? 'Available' : 'Unavailable';
}
```

**Page router — JavaScript**

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

export const getServerSideProps = async context => ({
  props: {
    enabled: await evaluate("context's countries include location's countryName", {
      context: {
        attributes: {
          countries: ['United States', 'Canada', 'Mexico'],
        },
      },
      route: context,
    }),
  },
});

export default function ConditionalFeature({enabled}) {
  return enabled ? 'Available' : 'Unavailable';
}
```

**Page router — TypeScript**

```tsx
import type {ReactNode} from 'react';
import {evaluate} from '@croct/plug-next/server';
import type {GetServerSideProps} from 'next';

type ConditionalFeatureProps = {
  enabled: boolean;
};

export const getServerSideProps: GetServerSideProps<ConditionalFeatureProps> = async context => ({
  props: {
    enabled: await evaluate<boolean>("context's countries include location's countryName", {
      context: {
        attributes: {
          countries: ['United States', 'Canada', 'Mexico'],
        },
      },
      route: context,
    }),
  },
});

export default function ConditionalFeature({enabled}: ConditionalFeatureProps): ReactNode {
    return enabled ? 'Available' : 'Unavailable';
}
```

Any attribute passed in the [`attributes`](/reference/sdk/javascript/api/plug/evaluate#options-attributes-prop) option will be available in the query as a [`context`](/reference/cql/data-types/web/web-context) variable.

## Explore

- [CQL reference](/reference/cql/expressions/basics): Learn how to write queries using the CQL language.
- [Evaluate function](api/functions/evaluate): Explore the function documentation and available options.
