How to create an Instagram Feed module for Vue Storefront
I’ve been working with Vue Storefront for the past few months and it’s been a great experience. It’s one of the few open-source solutions available to implement PWAs using Magento 2 (and many other e-commerce platforms) in the backend so it brings modern solutions out of the box to a lot of common requirements for web based applications (offline support, lazy loading, small bundle size, server side rendering, etc).
To get a basic understanding of how Vue Storefront works I thought it would be a good idea to document how to implement an Instragram feed in your store. It’s a relatively simple tasks but it involves many core concepts of Vue Storefront so it can be a useful case of “learn by doing”.
Before we start
It’s important to understand the Vue Storefront is a collection of multiple “pieces” working together, not a single big entity. The most significant ones would be:
- vue-storefront: handles the frontend of the store, it’s powered by (you guessed it) VueJS and many other packages that determine how the data should be displayed.
- vue-storefront-api: since Vue Storefront is 100% platform agnostic this service is needed to act as a middle layer between the frontend and the backend. In most cases we’ll use it to connect to Magento but it can interact with any number of providers, eg: WordPress, MailChimp, or in this case Instagram.
If you’re interested in knowing more about Vue Storefront architecture I recommend giving the official technical screencast a watch as it does a better job at explaining all the tools behind it that I ever could in this article.
Setting up the API endpoint
To get a user’s Instagram feed we need to use an access token to query Facebook’s Graph API. It’s not ideal to expose this kind of information in the front-end as it can lead to security vulnerabilities so we should do this server-side.
Luckily we can easily extend vue-storefront-api with custom endpoints that return the data we need. 🎉
We’ll start by creating the following index.js
file in src/api/extensions/instagram-api/
:
Basically what this does is extend Vue Storefront’s express Router with a new /feed
endpoint that will make a request to Facebook’s Graph API with our page ID and access token. If there’s any error it will return a 500
status code with the error response, if not it will return the user’s Instagram feed as a JSON array.
It also accepts an optional “limit” parameter to specify the maximum number of items to return.
As you can see we didn’t hardcode the page ID or the access token, as they will be project-specific these should be stored in the config/local.json
file.
Open the local.json
file and add an instagram
key to the extensions
list with the following information:
"instagram": {
"pageId": "FB PAGE ID",
"accessToken": "FB PAGE ACCESS TOKEN"
}
To get your page ID follow these instructions: facebook.com/help/community/question/?id=378910098941520
To get a “never expire” access token follow this SO answer: stackoverflow.com/a/35481577/455319
Now to enable our extension add “instagram-api” to the list of registeredExtensions
in your local.json
config file as well.
If everything went well you should see a list of the latest Instagram posts when you visit our custom vue-storefront-api endpoint /api/ext/instagram-api/feed
:
Setting up frontend component
Now that we have a way to securely retrieve our Instagram feed we can start thinking about how to display it. Since version 1.6 Vue Storefront encourages the use of modules to extend its functionality so this can be a good use case to use one.
Let’s create the following files in the src/modules/instagram-feed
folder:
index.ts
This is the entry point for our module, it’s mostly boilerplate code that sets up all the data required by our module. In our case it just registers a new module with the instagram-feed
name and registers the Vuex store.
store/index.ts
store/mutation-types.ts
This creates the actions, getters and mutations for Vue Storefront’s Vuex store. The most important part is the get
action that makes a request to the API we created earlier to fetch the latest Instagram posts, since this endpoint can be variable it’s a good idea to also store it in the config/local.json
file, so make sure to create a new parameter as well:
"instagram": {
"endpoint": "http://your-vue-storefront-api-url.com/api/ext/instagram-api/feed"
}
components/InstagramFeed.js
Finally our custom component which can be used as a mixin, gets the latests Instagram posts from the Vuex store on mount and exposes a feed
property that can be used in the template. It also allows us to change the feed limit with a custom limit
prop.
Now to register our custom module we include it in the src/modules/index.ts
file:
// Import module at the top
import { InstagramFeed } from '../modules/instagram-feed'// Add to "registerModules" array
export const registerModules: VueStorefrontModule[] = [
...
InstagramFeed
]
Displaying feed in the frontend
To finish it off all we need to do is create the markup to actually show the feed in our website.
To save some time let’s reuse the code that renders the “Get inspired” section that comes in the default theme. Create a InstagramFeed.vue
file in src/themes/default/components/theme/blocks/InstagramFeed/InstagramFeed.vue
:
This looks pretty much the same as the default TileLinks.vue
file, all we do here is use our InstagramFeed
mixin and loop over the feed
computed property to render the available media.
Let’s display our custom component on the homepage of our store, open the Home.vue
in src/themes/default/pages/Home.vue
and include the markup for the element we just created:
<template>
...
<section class="container pb60 px15">
<div class="row center-xs">
<header class="col-md-12 pt40">
<h2 class="align-center cl-accent">
{{ $t('Instagram') }}
</h2>
</header>
</div>
<instagram-feed limit="8" />
</section>
...
</template><script>
...
import InstagramFeed from 'theme/components/theme/blocks/InstagramFeed/InstagramFeed'export default {
components: {
...
InstagramFeed
}
}
</script>
If everything is right we’ll be able to see our Instagram feed on the homepage:
The cool thing about it is that since we’re reusing the TileLink
component markup we get the lazy loading and CSS transitions for free.
Wrapping up
We managed to use a good portion of the technologies that are part of Vue Storefront, however there are still a few things that can be improved, eg:
- TypeScript implementation
- Caching feed
- Storing media in Elastic Search
- And much more…
But as a quick introduction this module should showcase some of the features that make Vue Storefront a great tool to build e-commerce stores with. 👋🏽
The code for the module is available in GitHub, feel free to submit any issues and pull requests: