Flask Vue.js Integration Tutorial
Tags: python, flask, vue, javascript
Published: 2019-05-24 19:59:56

---
title: Flask Vue.js Integration Tutorial
published: true
description: A tutorial to integrate Vue.js with flask
tags: Python, Flask, Vue.js, Javascript
---

This tutorial answers the question, _"How do I integrate Vue.js with Flask?"_ Since you are reading this tutorial, I assume that you know that **Flask** is a Python microframework built for rapid web development. If you are not familiar with flask or probably think that I am going to talk about a thermos :stuck_out_tongue_winking_eye:, then I suggest reading about it [here](http://flask.pocoo.org/) before proceeding with this tutorial.

**Vue.js** is a progressive framework for building user interfaces. If you are not familiar with it, you can read about it [here](https://vuejs.org/v2/guide/).

Now that you are familiar with both Flask and Vue.js, we can begin. 

## Flask Setup
Let's install a couple of dependencies first:
```python
pip install --user cookiecutter
```
[Cookiecutter](https://cookiecutter.readthedocs.io/en/latest/readme.html) is an awesome command-line utility for quickly bootstraping project templates. We are using cookiecutter so that we don't spend too much time setting up the project. Remember, flask is not **batteries included** like [Django](https://www.djangoproject.com/), so quite a bit of work has to be put into the initial setup of a project.

Now that you have installed Cookiecutter, we need grab a project template. For this tutorial, we just need a simple flask API. Run the following commands:
```bash
cookiecutter gh:mobidevke/cookiecutter-flask-api-starter
```
You should get the following output:
```
repo_name [api-starter]: flask-vuejs-tutorial
api_name [Api]: api
version [1.0.0]: 1.0.0
```
A folder called **flask-vuejs-tutorial** should be created. Navigate into that folder and you should see the following structure:
```bash
├── app
│   ├── config.py
│   ├── factory.py
│   ├── __init__.py
│   ├── models
│   │   ├── base.py
│   │   ├── database.py
│   │   ├── datastore.py
│   │   └── __init__.py
│   ├── resources
│   │   ├── example.py
│   │   └── __init__.py
│   └── utils.py
├── pytest.ini
├── README.md
├── requirements.txt
├── settings.py
├── tests
│   ├── conftest.py
│   ├── __init__.py
│   ├── test_app.py
│   ├── test_models.py
│   ├── test_resources.py
│   └── utils.py
├── unit-tests.sh
└── wsgi.py

```
Beautiful, isn't it :smiley:? 

Before we proceed we need to setup a virtual environment. Run:
```
python -m venv venv
``` 
You can now open the project folder using your favourite IDE/Text Editor. Remember to activate the virtual environment before proceeding to the next step. 
Now we can install our dependencies. Run:
```python
pip install -r requirements.txt
```
Once done open `app/config.py`. You'll notice that this API template uses a postgres database connection. You can setup a postgres db with the necessary credentials, if you don't mind. Otherwise, replace the contents of that folder with the following lines of code:
```python
import os


class Config:
    ERROR_404_HELP = False

    SECRET_KEY = os.getenv('APP_SECRET', 'secret key')

    SQLALCHEMY_DATABASE_URI = 'sqlite:///tutorial.db'
    SQLALCHEMY_TRACK_MODIFICATIONS = False

    DOC_USERNAME = 'api'
    DOC_PASSWORD = 'password'


class DevConfig(Config):
    DEBUG = True


class TestConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'sqlite://'
    TESTING = True
    DEBUG = True


class ProdConfig(Config):
    DEBUG = False


config = {
    'development': DevConfig,
    'testing': TestConfig,
    'production': ProdConfig
}
```
We have removed all postgres configurations in favour of sqlite ones. If you want to use postgres, leave the `conf.py` file untouched.
We now need to export our flask application. Run:
```
export FLASK_APP=wsgi:app
```
Now that we have finished setting up our flask API, run:
```python
flask run
```
then open http://127.0.0.1:5000/example. You should see the following:
```json
{"message": "Success"}
```
## Vue.js setup
Now that our API is ready, we can proceed to bootstrap the vue application.
The first thing we need to do is install the vue cli. Run:
```bash
npm install -g @vue/cli
# OR
yarn global add @vue/cli
```
Once the installation finishes, you can check that you have the right version (3.x) with this command:
```bash
vue --version
```
At the root of your project folder run:
```bash
vue create web
```
I chose **default (babel, eslint)** as the preset and **yarn** as my package manager. If you are familiar with node projects you can go ahead and choose your preferred options. If not, just follow the defaults for this tutorial.
Now navigate into the new clearly created **web** folder and run:
```bash
yarn serve
# OR
npm run serve
```
If you navigate to http://localhost:8080/, you should see a **Welcome to Your Vue.js App** text.

Now we are ready to start the integrations. 
![Woohoo](https://media.giphy.com/media/3o7buiQeyYFamzRoR2/giphy.gif)

In the web folder, create a file called `vue.config.js` and paste the following contents:
```
const path = require('path');

module.exports = {
  assetsDir: '../static',
  baseUrl: '',
  publicPath: undefined,
  outputDir: path.resolve(__dirname, '../app/templates'),
  runtimeCompiler: undefined,
  productionSourceMap: undefined,
  parallel: undefined,
  css: undefined
};
```
**Note** If you are using Vue CLI 3.3 and above use `publicPath` instead of `baseUrl`.
Here, are defining some configurations for the vue cli. 
We are only interested in three fields: **assetsDir, baseUrl, outputDir**.
Let's start with the outputDir. 
This folder holds the location of the built vue files, that is, the folder that will hold the `index.html` that wil load the vue app. If you observe the path provided, you'll notice that the folder is inside the `app` module of the flask application.
The `assetsDir` holds the folder for the static files (css, js etc). **Note** It is relative to the value provided in the `outputDir` field.
Finally, the `baseUrl` field will hold the path prefix for the static files in the `index.html`. You can check [this](https://cli.vuejs.org/config/) to find out more information about other configuration options.
Now run:
```bash
yarn build
# OR
npm run build
``` 
If you open the `app` folder, you will notice that two new folders have been created, `templates` and `static`. They contain the built vue files.
Now create a `views.py` file in the `app` folder and paste the following contents:
```python
from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound

sample_page = Blueprint('sample_page', 'sample_page', template_folder='templates')


@sample_page.route('/sample')
def get_sample():
    try:
        return render_template('index.html')
    except TemplateNotFound:
        abort(404)

```
Now, what's going on here? 
Well, we are creating a flask blueprint named `sample_page` and adding a route to it. This route will render our vue app.

Open `__init__.py` and add the following lines below `app = f.flask`:
```
.....
app = f.flask
from .views import sample_page

app.register_blueprint(sample_page, url_prefix='/views')
```
Here, we are registering the blueprint we created earlier. 
We are giving the blueprint a url prefix so that our vue app is accessible from `/views/sample`.

The moment of truth has arrived.
![Moment](https://media.giphy.com/media/l2Je18AepQC2ma9mU/giphy.gif)


Open http://127.0.0.1:5000/views/sample you should see the  following:

![Image](https://i.ibb.co/xGzGmYG/screenshot-2019-05-24-22-13-52.png)

If you check the logs, you will see the built resources were loaded correctly:
```
 * Serving Flask app "wsgi:app"
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [24/May/2019 20:45:02] "GET /views/sample HTTP/1.1" 200 -
127.0.0.1 - - [24/May/2019 20:45:02] "GET /static/css/app.e2713bb0.css HTTP/1.1" 200 -
127.0.0.1 - - [24/May/2019 20:45:02] "GET /static/js/chunk-vendors.b10d6c99.js HTTP/1.1" 200 -
127.0.0.1 - - [24/May/2019 20:45:02] "GET /static/js/app.c249faaa.js HTTP/1.1" 200 -
127.0.0.1 - - [24/May/2019 20:45:02] "GET /static/img/logo.82b9c7a5.png HTTP/1.1" 200 -
127.0.0.1 - - [24/May/2019 20:45:02] "GET /views/favicon.ico HTTP/1.1" 404 -
```

You have successfully integrated Flask with Vuejs :smile:.

The source code for this tutorial can be found [here](https://github.com/michaelbukachi/flask-vuejs-tutorial).