# Extensions

{% hint style="info" %}
This guide is an entry point for working with extensions
{% endhint %}

## What is an extension

**Extension** is a reusable, isolated part of your application. It can contain any kind of source logic modifications, source being either a [theme](/themes/extensions-and-themes.md) or an extension.

**Extensions** allow to modify the source logic **without editing the source code**. The idea is to write additional logic - [plugins](/develop-an-extension/plugins.md), in order to intercept the initial logic and modify it in runtime.&#x20;

[Build configuration](/develop-an-extension/build-configuration-plugins.md) (webpack and babel) can also be modified from extensions.

## Initialize a project

Assuming that you have some project you are willing to use mosaic in, install Mosaic in your project by following any setup guide: [Next.js](/getting-started/nextjs.md), [CRA](/getting-started/create-react-app.md) or [Webpack](/getting-started/webpack.md). If you want to start a project from scratch, just create it with Next, CRA or manually with Webpack and follow the same steps.

## Prepare the source logic

A [namespace](/develop-an-extension/namespaces.md#namespace) should be set for the piece of functionality we are **willing to make available for plugins**. Using the "[magic comment](/develop-an-extension/namespaces.md#how-namespace-comments-work)" syntax is the most convenient option to do it. Our Babel plugin transforms this syntax into a simple function invocation.

In this guide, you will operate with the code depicted below, located in the corresponding directory.

{% tabs %}
{% tab title="Your code" %}
{% code title="./src/router.js" %}

```javascript
/* @namespace Router/getRoutes */ 
function getRoutes(options) { 
    return [ 
        '/home',
        '/my-account'
    ] 
}

const routes = getRoutes(); // routes + additional routes (from plugins)! 
app.setRoutes(routes)
```

{% endcode %}
{% endtab %}

{% tab title="After transpilation" %}

```javascript
const getRoutes = Mosaic.middleware(
    function getRoutes(options) { 
        return [ 
            // ...routes 
        ] 
    },
    'Router/getRoutes'
);

const routes = getRoutes(); 
// routes + additional routes (from plugins)! 
// see the explanation below
app.setRoutes(routes)
```

{% endtab %}
{% endtabs %}

## Create a package

**Within** your project, create a directory for your Mosaic modules (extensions). Conventionally, it is `<root>/packages`

```bash
.
├── 📁 packages/
│   └── 📁 @vendor/
│       └── 📁 additional-routes/
│           └── 📄 package.json
├── 📁 src/
│   └── 📄 router.js
└── 📄 package.json
```

**In that directory, create** a module with proper package.json [additional fields](/develop-an-extension/anatomy-of-an-extension.md#package-json), seen below. It is very **important** for this module to be recognised as Mosaic module by the plugin system.

{% code title="./packages/@vendor/additional-routes/package.json" %}

```javascript
{
    "mosaic": {
        "type": "extension"
    }
}
```

{% endcode %}

## Install and enable the module

[Install](/install-an-extension/use-a-local-extension.md) it into the package it interacts with. Remember to launch one of the scripts below in order to apply your installation!

{% code title="./package.json" %}

```javascript
{
    "scripts": {
        ...
        // TODO provide a linker package
        "postupdate": "...-scripts link",
        "postinstall": "...-scripts link"
    },
    "dependencies": {
        "@vendor/additional-route": "file:relative/path/to/the/module"
    }
}
```

{% endcode %}

Remember to [enable](/install-an-extension/enable-or-disable-an-extension.md) it afterwards!

{% code title="package.json" %}

```javascript
{
    "mosaic": {
        "extensions": {
            "@vendor/additional-route": true
        }
    }
}
```

{% endcode %}

## **Write a plugin**

Create a [plugin declaration file](/develop-an-extension/plugins.md#plugin-declaration-files) in the [proper directory](/develop-an-extension/anatomy-of-an-extension.md#file-structure) - `src/plugin/`&#x20;

Remember that there is a naming convention for these files - their names should end with `.plugin.js`

[Manipulate](/develop-an-extension/plugins.md#implement-proxy-function) the initial logic as you wish! You may have several plugins on a single namespace, if they are compatible with each other all of them will work!

{% code title="packages/@vendor/additional-route/src/plugin/math.plugin.js" %}

```javascript
const plugin = (args, callback) => {
    console.log(args);     // [options]
    console.log(callback); // function getRoutes(options) {...}

    const originalRoutes = callback(...args); // ['/home', '/my-account']
    const additionaloutes = ['/cart', '/contact-us'];
    
    return [
        ...originalRoutes, 
        ...additionalRoutes
    ];
};

export default {
    'Router/getRoutes': {
        function: plugin
    }
}
```

{% endcode %}

## See it in work!

Let's launch the project and see what the initial code will give us. If you followed the guide correctly, you will see that the behavior of `getRoutes` function has changed and now it acts as follows!

It will also log some stuff into the console (explained above).

```javascript
const routes = getRoutes(); // ['/home', '/my-account', '/cart', '/contact-us']
```

## Acknowledge other extensions' features

The plugin system, although is one of the main features of Mosaic, is not the only one. To find out more about it, check out the [in-depth guide](/develop-an-extension/plugins.md) dedicated to it.

Extensions can contain not only runtime logic, but also build configuration modifications.

{% content-ref url="/pages/-MZNczryQsVK9W\_7dWCI" %}
[Build configuration plugins](/develop-an-extension/build-configuration-plugins.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mosaic.js.org/hands-on-guides/quick-start.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
