Build an Instagram Stories Experience

Banner for a MediaJam post

Demola Malomo

According to Instagram, the engagement on the platform has ballooned to an average of 30 minutes per day since the introduction of stories. It enables users to post and view highlights about their activities. Stories are so popular that they are used on major social media platforms like Facebook, WhatsApp, LinkedIn, and Twitter.

This post will discuss how to quickly build an Instagram stories experience using Cloudinary and Nuxt.js. At the end of this tutorial, we will learn how to serve images using Cloudinary in Nuxt.js.

Nuxt.js is a vue-based frontend development framework that enables functionalities like server-side rendering, static site generation, file-system routing, components auto-import, and API endpoints for backend features.

Cloudinary offers a robust visual media platform to upload, store, manage, transform, and deliver images and videos for websites and applications.


We completed this project in a CodeSandbox, and you can fork it to run the code.

Github link here.


The following steps in this post require JavaScript and Vue.js experience. Experience with Nuxt.js isnโ€™t a requirement, but itโ€™s nice to have.

We also need a Cloudinary account to store the media files. Signup is completely free.

Getting Started

We need to create a Nuxt.js starter project by navigating to the desired directory and running the command below in our terminal.

1npx create-nuxt-app insta_stories && cd insta_stories

This command will ask us some questions on how to configure our application. We can answer the questions as shown below:

1Ok to proceed? (y) < PRESS "y" and hit ENTER>
2 project name: <PRESS ENTER>
3 programming langauge: <JAVASCRIPT>
4 package manager: <NPM>
5 UI framework: <TAILWIND CSS>
7 Linting tools: <ESLINT, PRETTIER>
8 Testing framework: <NONE>
9 Rendering mode: <UNIVERSAL (SSR/STATIC)
10 Deployment target: <STATIC/JAMSTACK HOSTING>
11 Deployment tools: <JSCONFIG.JSON>
12 Continous integration: <NONE>
13 Version control system: <GIT>

The command creates a Nuxt.js project with TailwindCSS called insta_stories, and navigates into the project directory.

TailwindCSS is a utility-first CSS framework packed with classes to help us style our web page.

We proceed to install @nuxtjs/cloudinary and vue-insta-stories ****dependencies with:

1npm install @nuxtjs/cloudinary vue-insta-stories @vue/composition-api

@nuxtjs/cloudinary is library for integrating Cloudinary with Nuxt.js.

vue-insta-stories is a customizable component for creating stories.

@vue/composition-api is a library for composing components. Itโ€™s a required dependency for vue-insta-stories.

Configuring Cloudinary in Nuxt.js First, we need to modify the nuxt.config.js file by adding @nuxtjs/cloudinary as a module in the modules section:

1modules: [
2 '@nuxtjs/cloudinary', //add this
3 ],

Next, we need to configure Cloudinary by adding a cloudinary section below the modules section as shown below:

1modules: [
2 '@nuxtjs/cloudinary',
3 ],
5 //add this
6 cloudinary: {
7 cloudName: '<your-cloud-name>',
8 useComponent: true,
9 },

The useComponent flag set to true lets us use the built-in Cloudinary components. Our cloud name is obtained from our Cloudinary dashboard.

Image sourcing and upload to Cloudinary

Next, we need to upload sample images from Unsplash to create our Instagram stories.

Stories Photos url

In our Cloudinary dashboard, we uploaded the images by clicking on the Media Library tab, clicking on Upload, selecting Web Address option, input the url, and clicking on the Arrow Button to upload.

Cloudinary console and upload button for other formats of upload

select web address and enter url

After uploading all the images, we will see them displayed on the console. To get the image URL, mouse hover on the image and click on the link icon. These URLs will come in handy when populating the image collection.

Uploaded image with copy icon higlighted

Set up the image collection

Next, we need to create a utils folder in the project root directory. In this folder, we create a stories.json file. This file contains image data for the stories.



Creating the Instagram Story

First, we need to navigate to the components folder, and in this folder, create an Info.vue file and add the code snippet below:

2 <div class="text-sm w-full lg:w-2/3">
3 <section class="flex items-center mb-4">
4 <h1 class="font-normal mr-6">Estelle_</h1>
5 <button
6 class="border border-gray-200 py-1 md:px-10 font-bold text-sm rounded-md"
7 >
8 Message
9 </button>
10 </section>
11 <div class="flex mb-4">
12 <div class="md:flex md:space-x-1 mr-8">
13 <p class="font-bold text-sm">13</p>
14 <p class="text-sm font-medium text-gray-400">posts</p>
15 </div>
16 <div class="md:flex md:space-x-1 mr-8">
17 <p class="font-bold text-sm">194</p>
18 <p class="text-sm font-medium text-gray-400">followers</p>
19 </div>
20 <div class="md:flex md:space-x-1 mr-8">
21 <p class="font-bold text-sm">182</p>
22 <p class="text-sm font-medium text-gray-400">following</p>
23 </div>
24 </div>
25 <p>
26 An online store ๐Ÿฌ we deal on all kinds of footwear ๐Ÿ‘ ๐Ÿ‘ž for both male and
27 female. Contact us โ˜Ž{" "}
28 <span class="text-blue-600">@08141703050</span>. Worldwide delivery ๐ŸŒ
29 <span class="text-blue-600">@Owerri</span>, Nigeria
30 </p>
31 <p class="text-xs py-5">
32 followed by <span class="font-bold">dpkreativ</span>
33 </p>
34 </div>
37 export default {}

The snippet above contains a placeholder for posts, numbers of followers, following and details just as we have it on Instagram.

Next, we modify the index.vue file in the pages folder to the following:

2 <div
3 class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center sm:pt-0"
4 >
5 <div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
6 <div
7 class="flex flex-col lg:flex-row items-center mt-8 bg-white overflow-hidden shadow sm:rounded-lg p-6"
8 >
9 <div
10 class="w-44 h-44 flex items-center justify-center border-indigo-400 border-4 mr-4 rounded-full cursor-pointer"
11 role="button"
12 @click="toggleStory"
13 >
14 <cld-image
15 :public-id="images[0]"
16 class="rounded-full w-40 h-40"
17 ></cld-image>
18 </div>
19 <Info />
20 </div>
21 </div>
22 <div
23 v-if="showStory"
24 class="absolute h-screen w-screen bg-black bg-opacity-70 top-0 h-100vh"
25 >
26 <section class="flex justify-end p-4">
27 <button
28 @click="toggleStory"
29 class="px-4 py-2 rounded-lg shadow-md bg-indigo-700 font-semibold text-white capitalize"
30 >
31 close
32 </button>
33 </section>
34 <section class="flex items-center justify-center">
35 <Stories
36 v-if="showStory"
37 :stories="images"
38 class="absolute top-10 left h-4/5 w-2/4"
39 />
40 </section>
41 </div>
42 </div>
46import { Stories } from 'vue-insta-stories'
47import images from '@/utils/stories.json'
48export default {
49 components: { Stories },
50 data() {
51 return {
52 images,
53 showStory: false,
54 }
55 },
56 methods: {
57 toggleStory() {
58 this.showStory = !this.showStory
59 },
60 },

The snippet above does the following:

  • Imports the image collection and Stories component
  • Creates data properties to manage imported image collection and conditionally show the story.
  • Creates the toggleStory method to toggle story visibility.
  • Markup to show a profile picture using Cloudinary and Info component.
  • Markup for the Stories component. The markup also configured the Stories component to render conditionally and passed the imported images as props.

With that done, we can start a development server using the command below:

1npm run dev


This post discussed how to build an instagram stories experience using Cloudinary and Nuxt.js.

You may find these resources helpful:

Demola Malomo

Software Engineer & Technical Writer

Demola is a software developer, technical writer, and product designer. He has a passion for designing and building scalable applications.