# Developing Apps in MOLGENIS

You can create add-on user interfaces using html+javascript. To be able to host your app inside MOLGENIS, you need to create an archive in a specific format. To get started right away, you can download an [example archive here](https://github.com/molgenis/molgenis/tree/69869f19ac37b353e2b66fe65c6191a81f50d645/docs/data/molgenis-app-example.zip). Following paragraphs will explain in detail how to construct and configure your resources to make it a certified MOLGENIS app.

## Archive structure

If you downloaded the example archive, you probably noticed that the structure of the archive is pretty straight forward.

```
|-- config.json
|-- index.html
|-- app-template.html
|-- js
    |-- example.js
|-- css
    |-- example.css
```

The index.html is your main entry point, and the contents will be interpreted and rendered by a FreeMarker engine. Relative to your index.html you can include js and css.

> note: If you use absolute paths, MOLGENIS is unable to serve your resources properly

### Example

The following example assumes we have a setup according to the tree structure shown in the previous paragraph.

*index.html*

```markup
<html>
  <head>
    <link href="css/example.css"/>
  </head>
  <body>
    <div class="container">
      <h1>This is an example of including resources with relative paths</h1>
    </div>
    <script src="js/example.js"></script>
  </body>
</html>
```

*example.js*

```javascript
alert('this is a wonderful example')
```

*example.css*

```css
.container {
    background: blue;
    height: 400px;
    width: 100%
}
```

> **For production usage**

*app-template.html*

This file is needed by the target MOLGENIS-instance. It will be used to render the index.html for the production app.

```javascript
<div id="app"></div>
```

## Configuration

The config.json is a small configuration file that will tell MOLGENIS about your app. It contains the following parameters

| Parameter            | type    | mandatory | Description                                                                                                                                                |
| -------------------- | ------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| label                | string  | yes       | The label used to name your app in the app manager screen                                                                                                  |
| description          | string  | yes       | A description for your app. Useful for making your app more findable in the app manager                                                                    |
| version              | string  | yes       | The version of your app. Used to manage app version, updating etc etc..                                                                                    |
| apiDependency        | string  | yes       | The version of the MOLGENIS REST api you used in your app. Can be used to give warnings about possible incompatibility with a specific version of MOLGENIS |
| name                 | string  | yes       | The name of the app. May not contain '/'                                                                                                                   |
| includeMenuAndFooter | boolean | yes       | If you want MOLGENIS to serve your app with the standard header (with menu and polyfill), and footer, set this value to **true**                           |
| runtimeOptions       | object  | no        | A map containing initial parameters you might want to give to your app on init                                                                             |

### Example

The following example shows every possible configuration option currently available

*config.json*

```javascript
{
    "label": "Example app",
    "description": "This is an example app",
    "version": "v1.0.0",
    "apiDependency": "v2",
    "name": "example",
    "includeMenuAndFooter": true,
    "runtimeOptions": {
        "language": "en"
    }
}
```

*Note that you can not create a config.json on your root path of the project. It will not build anymore.*

## Available javascript variables

MOLGENIS deploys apps with a bit of system information inside a global variable to get your app up and running. These are described below.

```javascript
window.__INITIAL_STATE__ = {
  baseUrl: '', // This is the root URL
  lng: '', // the language set by the system, allows you to implement i18n
  fallbackLng: '' // the fallback language set by the system, defaults to english (en)
}
```

## App resource caching

To enable caching of your resources, ensure your resource files have a hash code included in their file names. So instead of *example.js*, use *example.0943Ajd09834fd.js*.

Build tools like webpack already generate your source files with a hash code included in the file name.

## Using webpack for rapid app prototyping

To use webpack in rapid prototyping of your MOLGENIS apps, use the standard webpack template and make some small tweaks to make it a `build -> compress -> upload` workflow.

First you need to install 2 plugins:

```javascript
yarn --dev add zip-webpack-plugin@2.0.0
yarn --dev add generate-json-webpack-plugin
```

Make sure that you set the following two parameters in your production config.

In **config/index.js**

```javascript
const packageJson = require('../package')

module.exports = {
  // ...
  build: {
    // ...
    assetsSubDirectory: '',
    assetsPublicPath: '/plugin/app/' + packageJson.name,
    // ...
  }
}
```

In **build/webpack.prod.conf.js**

```javascript
plugins: [

  ...  

  new HtmlWebpackPlugin({
    filename: process.env.NODE_ENV === 'testing'
      ? 'index.html'
      : config.build.index,
    template: 'app-template.html',
    inject: true,
    minify: {
      removeComments: true,
      collapseWhitespace: true,
      removeAttributeQuotes: true
      // more options:
      // https://github.com/kangax/html-minifier#options-quick-reference
    },
    // necessary to consistently work with multiple chunks via CommonsChunkPlugin
    chunksSortMode: 'dependency'
  }),

  ...   

  new GenerateJsonPlugin('config.json', {
      name: packageJson.name,
      label: packageJson.name,
      description: packageJson.description,
      version: packageJson.version,
      apiDependency: "v2",
      includeMenuAndFooter: true,
      runtimeOptions: {
        language: "en"
      }
    }),

    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ]),

    new ZipPlugin({
      filename: packageJson.name + '.zip'
    })
  ]
```

These settings will ensure that your compiled resources are already in the correct file structure, and references to your resources are relative.

**app-template.html**

This file is needed by the target MOLGENIS-instance. It will be used to render the index.html for the production app.

```javascript
<div id="app"></div>
```


---

# 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://molgenis.gitbook.io/molgenis/8.4/for-developers/guide-development-apps.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.
