What's your favorite CMS for voice apps?



Since we added the CMS Interface in Jovo v2, we’re thinking a lot about content management for voice apps, and about what’s the best way to structure content.

Currently, Jovo offers:

Which CMS are you currently using? Any feature or potential integration that is missing?


I’m championing for Google Sheets! :trophy:

I’ll soon write some ways in which I use it, but one main reason why I like it so much is because it’s natural to write and structure content in sheets. Collaboration and versioning are built-in, and it’s so flexible that you can bend it to cover so many different use cases!

Here are some of the things I use them for:

  • Managing the translation ressources for i18n in one or more languages
  • Managing content items
  • Setting configuration parameters (especially for fine-tuning game balance)
  • Updating usage-dependent parameters (highscores and frequencies of answers, e.g. for ‘x% of users think like you’)
  • Managing simple voice app logic (what I call ‘microstates’)

The downside is that integrating private Spreadsheets takes a few steps (b/c of JWT authentication, but there’s a neat tutorial by @jan covering this), and that fetching the content from the Google API takes a few hundred milliseconds the first time round (which can be worked around).


Yes, I like this too. I want to dive deeper into Airtable though. Seems like there is a lot of powerful stuff that can be built with it, which is currently only possible with Google Sheets while doing workarounds.

There are also some other emerging platforms that we could look into like Coda. It’s very flexible and allows people to write apps without code by plugging together different “docs” as they call them. They offer a lot of templates and there is a Maker Festival on Product Hunt in collaboration with them.


Great topic ! I haven’t actually had time to get back to this. My next project will very likely use Airtable, I’ll know more in the next few days. Ideally, I would like to use a headless cms. I have tried a few, just exploring the UX and have not yet found something perfect. My next exploration will most likely involve something like https://strapi.io/. I like that it’s open source so it’s possible to fix issues and improve it if necessary. Ideally, jovo would provide a GraphQL plugin allowing us to fetch data from such a CMS and possibly even from different sources (an image or video store, database, CMS, etc…).


That sounds great. Do you have a way to fetch the data in mind?

For the sheets/tables in Google Spreadsheets/Airtable, we use the sheet name to access data, like this.$cms.sheetName.key. Would you use it differently with GraphQL? (I’m sorry, I’m very new to the whole concept of GraphQL)

Also: Welcome to the Jovo Community Forum, @kaaloo :tada:


I haven’t given that much thought @jan but ideally it would be possible to use something more semantic because you can model the data in terms of the concepts involved like Intent, Response, Image, Audio, etc… So for instance you could do something like this.$cms.helloIntent.response.backgroundImage.url to access the background image for an Alexa template for the HelloIntent. Using something like the Apollo Client would help with a lot of the issues involved such as caching although it might be a bit of an overkill.


Hi Florian! I am curious about your note above re: collab and versioning. Currently any changes I make are go live instantly. I would like to make a new version that I can make changes to in dev, while not effecting the live skill.

How have you approached this?


Hi @natrixx, thanks for asking! :smiley:

What I was referring to when mentioning the built-in versioning of Google Sheets is the version history where you can see who changed what when, and restore earlier versions.

But it’s entirely possible to build a staging functionality with Google Sheets too, even though it’s not quite built-in, and I have actually done it with our Jovo Studios #VoiceGame Brain Pain.

The key idea here is to use either single tabs/sheets or the entire spreasheet as stages, depening on your scope, i.e. if it’s only the responses that need to be staged, or the content of other sheets too.

So, in case of single sheets, e.g. responses:

  1. Make a copy of your responses sheet, and name one responses live and the other responses dev
  2. Make the name of your responses sheet an enivronment variable like CM_SHEET_RESPONSES. For your local development stage, use a .env file with the dotenv package to set the value of this variable to responses dev.
  3. For your production stage, use Lambda’s environment variables to set it to responses live.
  4. Now you can work in responses dev without it interfering with the live Skill. Once you’re ready to push the state of responses dev live, do either of the following:
    4a. Delete/archive the sheet responses live, rename the sheet resonses dev to responses live, and make a fresh copy responses dev from responses live.
    4b. Change the value of the environment variable accordingly.

In case you need to have multiple sheets in stages, I would use entirely different spreadsheets per stage:

  1. Make a copy of your spreadsheet and invite the same service account user.
  2. Make the ID of your Google spreadsheet an enivronment variable like CM_SHEET_ID , and use different values for your development and production stage.
  3. If you want to push your dev version life, I would do so by changing the value of CM_SHEET_ID in the live version. You can then either archive, delete or reuse the previous production Spreadsheet.

Hope this helps! Please let me know if you have thoughts or questions to this approach!


Thanks @Florian! For my needs I think something like your last option would work best! I will toy around with it some more next week and be back with more questions if I have them. :smile: