Skip to content
Shop

Use Vue with Flask & HTMX

May 31, 2025

You will learn how to set up your flask app to use Vue and HTMX.

What you will need:

  • Flask - Python web framework
  • Vue CDN - for snappy frontend UI
  • Tailwind CDN - for fast CSS styling
  • HTMX - for a more dynamic frontend (not heavily used)

Create a new Flask App

Create the folders for your flask app. You should be able to copy the content below and paste it into your terminal. You can also create the folders manually using your mouse and keyboard. the app_name/ folder can be called whatever the name of your app is. For example you can do mkdir inventory_app instead of mkdir app_name.

bash
mkdir app_name
cd app_name
touch app.py
mkdir templates
touch templates/index.html
mkdir static
touch static/style.css
touch static/index.js

This is the folder structure of the app.

markdown
	app_name/
		templates/
			index.html
		static/
			index.js
			style.css
		app.py

Install dependencies

Create a virtual environment and install flask.

bash
python3 -m venv .venv
source .venv/bin/activate
pip3 install flask

Configuration

Set up some configuration.

html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/vue@3"></script>
    <title>Method 1 - Vue in Jinja</title>
</head>

<body>
    <div id="app">
        <p>{{ greeting }}</p>
        <p>[[ greeting ]]</p>

        <button hx-get="/clicked" hx-swap="outerHTML">
            Click Me
        </button>
    </div>
    <script src="https://unpkg.com/htmx.org@2.0.4"></script>
    <script src="{{ url_for('static', filename='index.js') }}"></script>
</body>

</html>
js
const app = Vue.createApp({
      delimiters: ['[[', ']]'],
      data() {
        return {
          greeting: 'Hello from Vue 3 + Flask!'
        }
      }
    })

app.mount('#app')

The Code

All components live in /templates/. CSS and Javascript files live in /static/. Copy the code in the files below to the appropriate files in your project.

python
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html", **{'greeting': 'Hello from Flask!'})

@app.route("/clicked")
def clicked():
    return 'You clicked'


if __name__ == '__main__':
    app.run(debug=True,port=4000)

Run the App

bash
python3 app.py

Vite + Vue + Flask Version

You can separate the frontend Vue code from the backend flask code using the steps below. Please note that I am using Vite, but you can just as well use the Vue CLI or other frontend frameworks like React or Svelte.

You will need:

Create two folders. One for your backend code and another for your frontend code.

bash
mkdir backend
mkdir frontend

The Backend

The backend will be similar to the flask portion above but we will add CORS and rename app.py to server.py so that we know this is a backend server (see server.py below).

python
from flask import Flask, render_template
from flask_cors import CORS  # Import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def index():
    return render_template("index.html", **{'greeting': 'Hello from Flask!'})

@app.route("/clicked")
def clicked():
    return 'You clicked'

if __name__ == '__main__':
    app.run(debug=True,port=4000)

The Frontend

Change your directory to the frontend directory and create your vue frontend using vite. Set your app's name to something like app_name and select Vue then Javascript (you can select Typescript if you prefer that), and finally, change directory into the new app_name directory

bash
cd frontend
yarn create vite
cd app_name

Update the index.html file in the frontend folder as follows. We need to add a meta tag for htmx to allow us to fetch data from the flask backend.

Now, you can use HTMX in any vue component (See Component.vue)

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="htmx-config" content='{"selfRequestsOnly":false}'>
    <!-- Needed so that you don't get an invalidPath error -->
    <title>Vite + Vue</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="https://unpkg.com/htmx.org@2.0.4"></script>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
html
<template>
<button hx-get="http://127.0.0.1:4000/" hx-swap="outerHTML">
Click Me
</button>
</template

<script setup>
</script>

Run the frontend and backend with a bash script

We can use a bash script to run the frontend and backend at the same time. Add a file named run.sh (you can call it whatever you want) at the same level as the frontend and backend folders and add the following.

bash
#!/bin/bash

# Start backend in background
cd backend
python3 server.py &

# Capture the backend PID if you want to stop it later
BACKEND_PID=$!

# Move to frontend and start dev server
cd ../frontend/flask-vue
yarn dev

# Optional: Kill backend when frontend exits
kill $BACKEND_PID

To run the script run bash run.sh.

To make this script executable, you can run it by giving the file execution permissions:

bash
chmod +x run.sh

After that, you can execute the script by running:

bash
./run.sh

Resources