Last updated Sep 24, 2024

Setting up the CSE schema-loader

Client-side Extensions uses graphql-style syntax to define schemas. Schemas define the attributes and types expected from extensions to work correctly on a given extension point.

In order to use the schemas, it's necessary to install and configure the @atlassian/clientside-extensions-schema webpack loader.

1. Installation

Add @atlassian/clientside-extensions-schema as a dependency of your project:

1
2
yarn add -D @atlassian/clientside-extensions-schema

# or

npm install --save-dev @atlassian/clientside-extensions-schema

2. Configure schema-loader

In your webpack configuration, configure the loader to match .cse.graphql files as follow:

1
2
// #webpack.config.js

module.exports = {
    // your webpack config
    entry: {
        /**/
    },
    output: {
        /**/
    },
    plugins: [
        /**/
    ],
    // ...

    module: {
        rules: [
            // Add a rule entry to the list of loaders
            {
                test: /\.cse.graphql$/,
                loader: '@atlassian/clientside-extensions-schema/loader',
                options: {
                    // You can specify a working dir
                    cwd: path.resolve(__dirname, 'src', 'schemas'),
                },
            },
        ],
    },
};

After configuring the loader, you will be able to import the hooks and components directly from the schema as follows:

schema.cse.graphql

1
2
"""
---
extensionPoint: example.extension-point
---
"""
type Schema {
    """
    Extension type
    """
    type: LinkExtension!

    """
    Label of the link
    """
    label: String!

    """
    URL of the link
    """
    url: String!
}

extension-point.tsx

1
2
import React from "react";
import { useExtensions } from "./schema.cse.graphql";

const ExampleExtensionPoint = ({ context }) => {
    const extensions = useExtensions(context);

    return (
        <>
            {extensions.map(({attributes}) => (<a href={attributes.url}>{attributes.label}</a>)}
        </>
    )
}

export default ExampleExtensionPoint;

3. Sharing scalars and types

CSE provides a set of default scalars and types that you will be using very often, but there are cases where you would like to share your own types and scalars between schema definitions.

To do so, you can declare files with a name like *.type.graphql and configure the loader to include those definitions for all your schemas as follows:

1
2
// #webpack.config.js

module.exports = {
    // your webpack config
    entry: {
        /**/
    },
    output: {
        /**/
    },
    plugins: [
        /**/
    ],
    // ...

    module: {
        rules: [
            {
                test: /\.cse.graphql$/,
                loader: '@atlassian/clientside-extensions-schema/loader',
                options: {
                    cwd: path.resolve(__dirname, 'src', 'schemas'),
                    // configure a pattern for your own shared types
                    providedTypes: '**/*.type.graphql',
                },
            },
        ],
    },
};

After configuring the loader, you will be able to use shared definitions between your schemas as follow:

user.type.graphql

1
2
type User {
    name: String

    age: Number

    lastLogin: Number

    isAdmin: Boolean
}

schema.cse.graphql

1
2
"""
---
extensionPoint: example.extension-point
---
"""
type Schema {
    """
    Extension type
    """
    type: LinkExtension!

    """
    Label of the link
    """
    label: String!

    """
    URL of the link
    """
    url: String!
}

type ContextSchema {
    """
    Using custom type to define a property of context
    """
    user: User
}

Jest support

This package provides a 'jest-transformer' for .graphql-schema files. When using webpack to load your extensions with the schema-loader at @atlassian/clientside-extensions-schema/loader, you need to tell your test-runner how to interpret those imports. This jest-transformer will do exactly this, if you run your tests using jest.

To use it, add the following entry to your Jest jest.config.js config file:

1
2
module.exports = {
    transform: {
        // A custom GraphQL transformer that provides React hooks and components for CSE
        '^.+\\.extension\\.graphql$': require.resolve('@atlassian/clientside-extensions-schema/jest-graphql-transformer.js'),
    },
};

The match at the beginning ('^.+\\.extension\\.graphql$') has to match your extensions naming schema and may differ from the above. Ideally you want to use the same as is being used for the schema-loader in your webpack config.

Rate this page: