How to contribute a new framework to Sitecore JSS
Tags: sitecore, jss, javascript, tutorial
Published: 2023-07-15 13:48:30

Hey there :wave:!  I'm pretty sure that there are some developers who would like to contribute a new framework to JSS, at first glance it looks a bit more complex though.
Out of the box JSS provides a [**create-sitecore-jss**](https://www.npmjs.com/package/create-sitecore-jss) npm package. See more information on how to scaffold a new sample app in a [documentation](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/the-jss-app-initializer.html).

For the creation of the samples JSS uses an initializers approach. Let me highlight some major terms before moving forward.

[**Initializer**](https://github.com/Sitecore/jss/tree/dev/packages/create-sitecore-jss/src/initializers) - the process for handling the creation of the selected template.

[**Template**](https://github.com/Sitecore/jss/tree/dev/packages/create-sitecore-jss/src/templates) - the sample populated by ejs tokens. Templates are divided into types: 
- **base** - contains all the files, base features for the application (e.g. [nextjs](https://github.com/Sitecore/jss/tree/dev/packages/create-sitecore-jss/src/templates/nextjs)).
- **add-on** - provides additional features for the base template. Multiple add-on templates can be applied to the base (e.g. [nextjs-styleguide](https://github.com/Sitecore/jss/tree/dev/packages/create-sitecore-jss/src/templates/nextjs-styleguide)).

I will walkthrough the example of adding a Nuxt framework into the [create-sitecore-jss](https://github.com/Sitecore/jss/tree/dev/packages/create-sitecore-jss). Let's consider that Nuxt will be styleguide based.

### 1. Create a new initializer :white_check_mark:
Firstly, we need to add an initializer entry point.
I create a new folder under _src/initializers/nuxt_. Let's add required scripts:

#### index.ts

```ts
import path from 'path';
import inquirer from 'inquirer';
import { prompts, NuxtAnswer } from './prompts';
import { Initializer, transform } from '../../common';
import { NuxtArgs } from './args';

export default class ReactNativeInitializer implements Initializer {
  // Required to point that template is base
  get isBase() {
    return true;
  }

  async init(args: NuxtArgs) {
    // Ask for required parameters e.g. appName, hostName 
    const answers = await inquirer.prompt<NuxtAnswer>(prompts, args);

    // Merge framework specific and base scaffolding related answers
    const mergedArgs = {
      ...args,
      ...answers,
    };

    const templatePath = path.resolve(__dirname, '../../templates/nuxt');

    // Executes scaffolding process
    await transform(templatePath, mergedArgs);

    const response = {
      appName: answers.appName,
    };

    // Return response to be accepted by next add-ons
    return response;
  }
}
```

#### args.ts

It defines a type of value that we accept in the initializer and pass to the next add-ons. We have arguments that will be passed by default to the initializer. I added a new _teamcity_ property that we will request below.

```ts
import { ClientAppArgs } from '../../common';
import { NuxtAnswer } from './prompts';

type NuxtCustomArgs = {
  teamcity: boolean;
};

export type NuxtArgs = ClientAppArgs & Partial<NuxtAnswer & NuxtCustomArgs>;

```

#### prompts.ts

It defines questions that we want to ask for customer. We have default prompts that you can extend by adding an additional question.

```ts
import {
  ClientAppAnswer,
  clientAppPrompts,
  StyleguideAnswer,
  styleguidePrompts,
} from '../../common';

const customPrompts = [
  {
    type: 'confirm',
    name: 'teamcity',
    message: 'Do you want to apply Teamcity integration?',
    default: false,
  },
];

export type NuxtAnswer = ClientAppAnswer & StyleguideAnswer;

export const prompts = [...clientAppPrompts, ...styleguidePrompts, ...customPrompts];
```
### 2. Create a new template :white_check_mark:
I create a new folder under _src/templates/nuxt_. Here you need to add all the required files you want to contribute. In case of Nuxt it can be Nuxt sample app but extended with JSS.

### 3. Introduce a new _sitecore-jss-nuxt_ npm package :white_check_mark:
I create a new npm package in a repository under _packages/sitecore-jss-nuxt_ in order to place all the components, enhancers, utils specific to Nuxt. We need to reference this package in a sample app. Some part of the functionality can be re-exported from [sitecore-jss](https://github.com/Sitecore/jss/tree/dev/packages/sitecore-jss), like data fetching utils, models, etc. You can take a look at [_sitecore-jss-react_](https://github.com/Sitecore/jss/tree/dev/packages/sitecore-jss-react) as an example.

### 4. Let's test it out :white_check_mark:
In the CLI run
```
create-sitecore-jss
```
Here we go, Nuxt is present in a list
![create-sitecore-jss](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1a3zx16fqwdbz4e2og04.png)

And here is a last question we wanted to ask about Teamcity integration

![Teamcity question](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1v436k8fz17v5l6kazz9.png)

The new application has been successfully scaffolded!:star:

![create-sitecore-jss result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3wezmy6645gb144ugutx.png)

### Wrap up :sunglasses:
That's all for this article. Next time I will explain on how to contribute a new add-on for the base template. Thank you for your attention! See you in [**LinkedIn**](https://www.linkedin.com/in/illia-kovalenko-045a45150/) [**Instagram**](https://www.instagram.com/illia__kovalenko) [**GitHub**](https://github.com/illiakovalenko) :wave: