---
title: Providing context - Client-side Extensions
platform: server
product: clientside-extensions
category: devguide
subcategory: extension-points
date: '2024-09-10'
---

# Providing context

{{% note %}}
This is a continuation of the work done in [2. Rendering extensions](/server/framework/clientside-extensions/guides/extension-points/rendering-extensions).
{{% /note %}}

In this section you will learn more on:

-   What context is
-   How to define a schema for your context
-   How to share a context object with extensions

You'll continue working on the tutorial page: http://localhost:7990/bitbucket/plugins/servlet/extension-points

## Context

In CSE, context allows you to share information with extensions like the state of the
page where the extension is rendered, or a user's session. The context is a contract between your extension point and the extension developers, and as
such, it needs to be well documented and typed.

Before you share any context with extension, you first need to define a `ContextSchema` that
will validate that the information you're sharing is correct, and also generates the
documentation for you.

## Defining a schema for your context

The schema for your context needs to be declared in the same file where you declared your Schema,
and it uses the same [graphql-style syntax](https://spec.graphql.org/June2018/).

On `/src/main/my-app/extensions/extension-points-tutorial/schema.cse.graphql`, write:

```graphql
"""
---
extensionPoint: extension.points.tutorial
---
"""
type Schema {
    # your attributes...
}

type ContextSchema {
    user: String

    luckyNumber: Number
}

```

`ContextSchema` is a graphql type that defines the keys and values of the context you are going to share with extensions.
In this case, your context will share an object with a `user` and `luckyNumber` attribute.

## Sharing context with extensions

Once the `ContextSchema` is defined, all the helpers imported from the schema using CSE schema
loader will be aware of it, and will expect this context object to be passed as an argument
with the right properties.

On `./src/main/my-app/extensions/extension-points-tutorial/extension-points-page.jsx`:

```jsx
import React, {useState} from 'react

import { useExtensions } from './schema.cse.graphql';

const MyPage = () => {
    const [userInfo, setUserInfo] = useState({user: "Jon Doe", luckyNumber: 42});
    const extensions = useExtensions(userInfo);

    const renderExtension = extension => { /* rendering extension logic */};

    return (
        <PageContainer>
            <h2>extension.points.tutorial</h2>
            {extensions.map(renderExtension)}
        </PageContainer>
    );
};

/** page declaration for guides only **/
```

Reload the page and now you should see that the panel extension renders the context received
on the screen.

If you attempt to pass a context object that doesn't satisfy the `ContextSchema`, or don't
pass any context at all, the CSE runtime will throw an error and point you to where the
error is happening. Try it!

## Context change

Most of the time, the context you provided will be something that changes depending on what
the user does with the product. Thanks to the use of hooks, every time the context changes, it
triggers a recalculation of the extension's attributes, validates them and returns them
so that you can re-render them.

Take for example a change of the `luckyNumber` of the user every 10 seconds.

On `./src/main/my-app/extensions/extension-points-tutorial/extension-points-page.jsx`:

```jsx
import React, { useState } from 'react';

import { useExtensions } from './schema.cse.graphql';

const MyPage = () => {
    const [userInfo, setUserInfo] = useState({ user: 'Jon Doe', luckyNumber: 42 });
    const extensions = useExtensions(userInfo);

    useEffect(() => {
        const interval = setInterval(() => {
            setUserInfo({
                ...userInfo,

                luckyNumber: Math.floor(Math.random() * 42),
            });

            return () => clearInterval(interval);
        }, 10000);
    }, []);

    const renderExtension = (extension) => {
        /* rendering extension logic */
    };

    return (
        <PageContainer>
            <h2>extension.points.tutorial</h2>
            {extensions.map(renderExtension)}
        </PageContainer>
    );
};

/** page declaration for guides only **/
```

If you reload the page, you should see the panel extension rendering the new context every
10 seconds with a new lucky number.

## Recap and next steps

So far, you've learned:

-   How to share information with extensions
-   How to define a schema to validate your context
-   How the extension's attributes are recalculated when context changes.

Next, you're going to learn how to use your schema to provide [extension point documentation](/server/framework/clientside-extensions/guides/extension-points/extension-point-documentation).
