App Configuration

The app configuration in app.ts is the place where you can add plugins, components, and other configurations to your Jovo app. For project (CLI) related configuration, take a look here.

Introduction

📦src
 ┣ 📜app.dev.ts
 ┣ 📜app.ts
 ┗ ...

The app configuration files in the src folder are the main entry point of your Jovo apps. They usually include the following elements:

  • Components can be registered
  • Plugins and Hooks can be added to extend the framework functionality
  • Service providers can be added for dependency injection
  • Framework configurations, like logging behavior, can be modified

Here is an example app.ts file:

import { App } from '@jovotech/framework';
import { AlexaPlatform } from '@jovotech/platform-alexa';
import { GlobalComponent } from './components/GlobalComponent';
import { LoveHatePizzaComponent } from './components/LoveHatePizzaComponent';
// ...

const app = new App({
  /*
  |--------------------------------------------------------------------------
  | Components
  |--------------------------------------------------------------------------
  |
  | Components contain the Jovo app logic
  | Learn more here: www.jovo.tech/docs/components
  |
  */
  components: [GlobalComponent, LoveHatePizzaComponent],

  /*
  |--------------------------------------------------------------------------
  | Plugins
  |--------------------------------------------------------------------------
  |
  | Includes platforms, database integrations, third-party plugins, and more
  | Learn more here: www.jovo.tech/marketplace
  |
  */
  plugins: [new AlexaPlatform()],

  /*
  |--------------------------------------------------------------------------
  | Other options
  |--------------------------------------------------------------------------
  |
  | Includes all other configuration options like logging
  | Learn more here: www.jovo.tech/docs/app-config
  |
  */
  logging: true,
});

Jovo also supports staging that makes it possible to have different app versions for different deployment environments. Each Jovo project usually comes with at least two files for this:

Learn more about Jovo app configuration in the following sections:

Ways to Add Configurations

There are three ways how app configurations can be done:

  • Using the new App() constructor in app.ts for default configurations.
  • Using app.configure() for stage-specific configurations.
  • Using app.use() to add specific plugins and components anywhere in the app.

In the app.ts (example), the configuration is added like this:

import { App } from '@jovotech/framework';
// ...

const app = new App({
  // Configuration
});

On top of the default configuration, you can add stages with specific options that can be added like this, for example in an app.dev.ts (example) file:

import { app } from './app';
// ...

app.configure({
  // Configuration
});

Both the constructor and configure() support the full range of configuration elements.

The third option is the use() method. It allows you to add plugins and components anywhere in the app:

import { app } from './app';
import { SomePlugin } from './plugin';
// ...

app.use(
  new SomePlugin({
    // Plugin Configuration
  }),
);

Configuration Elements

The configuration object that can be passed to both the constructor and the configure() method contains components, plugins, providers, logging, and routing.

{
  components: [
    // ...
  ],
  plugins: [
    // ...
  ],
  providers: [
    // ...
  ],
  logging: {
    // ...
  },
  routing: {
    // ...
  }
}

Components

You can register root components with your app by adding them to the components array:

import { GlobalComponent } from './components/GlobalComponent';
// ...

{
  components: [
    GlobalComponent
    // ...
  ],
  // ...
}

Learn more about component registration here.

Plugins

You can add plugins to the plugins array like this:

import { AlexaPlatform } from '@jovotech/platform-alexa';

// ...

{
  plugins: [
    new AlexaPlatform({
      // Plugin Configuration
    })
    // ...
  ],
  // ...
}

Each plugin has its own configuration options which you can find in the respective plugin's documentation.

Additionally, each plugin config includes a skipTests option that makes sure that unit tests don't use that plugin:

{
  plugins: [
    new SomePlugin({
      // ...
      skipTests: true,
    })
  ],
}

You can also access a specific plugin like this:

app.plugins.<PluginConstructor>

// Example
app.plugins.SomePlugin

This can be helpful if you want to add additional configurations to the default plugin config outside app.ts. See staging for more information.

Providers

You can add service providers for dependency injection like this:

import { OrderService } from './services/OrderService';
// ...

{
  // ...

  providers: [
    OrderService,
    // ...
  ],
}

It is also possible to use the provide option to specify a token, for which you want to inject a dependency, separately from the injected value or type. Learn more about the different provider types here.

{
  providers: [
    {
      provide: OrderService,
      useClass: MockOrderService,
    },
    // ...
  ]
}

Logging

Logging is enabled by adding the following to the app config:

{
  // ...

  logging: true,
}

You can also add granular configurations by turning logging into an object, for example:

{
  // ...

  logging: {
    request: true,
    response: false,
    // ...
  }
}

Learn more about logging and its configuration options here.

Routing

Routing configurations are added to the routing object:

{
  routing: {
    intentMap: {},
    intentsToSkipUnhandled: [],
  },
  // ...
}

intentMap

Especially with apps that work across different platforms, it might happen that different platforms use different intent names.

intentMap provides a global way to map incoming intents to a unified intent that can be used in your handler routing.

{
  routing: {
    intentMap: {
      'AMAZON.HelpIntent': 'HelpIntent',
      // ...
    },
    // ...
  },
  // ...
}

It's also possible to add an intentMap to platforms like Alexa. The platform intentMap then gets merged into the global routing.intentMap.

{
  plugins: [
    new AlexaPlatform({
      intentMap: { // Gets merged into global intentMap below
        'AMAZON.HelpIntent': 'HelpIntent',
        // ...
      },
    }),
    // ...
  ],
  routing: {
    intentMap: {
      'HelloIntent': 'StartIntent',
      // ...
    },
    // ...
  },
}

For platforms like Alexa that already come with an intent in their requests, the mapped intent name is added to the root of the $input object:

{
  type: 'INTENT',
  intent: 'HelpIntent',
}

If you're using an NLU integration, the original intent stays in the nlu property and the mapped intent is added to the root of $input:

{
  type: 'TEXT',
  text: 'My name is Max',
  nlu: {
    intent: 'MyNameIsIntent',
    entities: {
      name: {
        value: 'Max',
      },
    },
  },
  intent: 'MappedMyNameIsIntent',
}

intentsToSkipUnhandled

intentsToSkipUnhandled includes all intents that shouldn't be fulfilled by an UNHANDLED handler.

{
  routing: {
    intentsToSkipUnhandled: [
      'HelpIntent'
    ],
    // ...
  },
  // ...
}

Learn more about intentsToSkipUnhandled here.

Staging

Stage-specific configurations from a file called app.<stage>.ts get merged into the default configuration from app.ts.

For example, most Jovo projects include an app.dev.ts (example) file that comes with specific configuration for local development (FileDb, Express server and the Jovo Debugger).

You can create a new stage like this:

$ jovo new:stage <stage>

# Example that creates a new app.prod.ts file
$ jovo new:stage prod

This creates a new file app.prod.ts. In the process, you can select plugins and a server integration to work with this stage. You can find an example app.prod.ts file here.

Typically, a stage app config uses the configure() method to modify the configuration.

import { app } from './app';
// ...

app.configure({
  // Configuration
});

It is also possible to reference a plugin from the default configuration in app.ts and add plugins to it using the use() method.

Here is an example for Dashbot Analytics being added to Alexa in app.prod.ts:

// Example: app.prod.ts

import { app } from './app';
import { DashbotAnalytics } from '@jovotech/analytics-dashbot';
// ...

app.plugins.AlexaPlatform.use(new DashbotAnalytics({ apiKey: '<yourApiKey>' }));