I want to use Vue.js and Flask together: Vue.js for a dynamic front-end, and Flask for the back-end. How can I do that?
I recently had this problem (combining Vue.js and Flask).
There are at least two ways to combine them, depending on whether you're creating 1) a simple Vue.js app or 2) a more-complicated Vue.js app that needs to use a module bundler like Webpack to combine Single-File Components or npm packages.
Simple Vue.js app:
This is actually fairly easy and very powerful on its own:
.html file. Otherwise just open whatever .html template file you want the app to be in.
If you're OK with having your Vue.js JavaScript code in the same file as your HTML, below is a simple "Hello World" example template you can use to get a sense of what needs to be in the Flask template file:
{{ message }}
static folder, name it after this app you want to create.
.html template file include a script tag to include Vue.js.
div in the .html template file that has an id of app.
If you are using Jinja2 to render your templates, you will need to add a few lines of code to tell Jinja2 to not use the {{ }} syntax to render variables, because we need those double-curly-brace symbols for Vue.js. Below is the code you need to add to your app.py to do this:
class CustomFlask(Flask):
jinja_options = Flask.jinja_options.copy()
jinja_options.update(dict(
variable_start_string='%%', # Default is '{{', I'm changing this because Vue.js uses '{{' / '}}'
variable_end_string='%%',
))
app = CustomFlask(__name__) # This replaces your existing "app = Flask(__name__)"
.html and .js files.
Easy!
More-complicated Vue.js app using Webpack:
npm install -g @vue/clivue create my-projectserver folder and a client folder, where the server folder contains the Flask server code, and the client folder contains the Vue.js project code.app.html file is created in your Flask server/templates folder, and the static JavaScript and CSS needed by app.html is created in a server/static/app/ folder, isolated from the static assets used by the non-Vue portions of you Flask app.npm run build from within the folder containing your Vue.js project, which will generate an .html file and several static files (JavaScript and CSS).The exact changes I made to my Webpack config (via my git commit):
client/build/webpack.dev.conf.js:
new HtmlWebpackPlugin({
- filename: 'index.html',
- template: 'index.html',
+ filename: 'app.html',
+ template: 'app.html',
Here (above) I'm changing the name of the Vue.js 'launch' file to app.html so that it doesn't conflict with my Flask app's 'index.html'.
client/config/index.js:
module.exports = {
build: {
env: require('./prod.env'),
- index: path.resolve(__dirname, '../dist/index.html'),
- assetsRoot: path.resolve(__dirname, '../dist'),
- assetsSubDirectory: 'static',
- assetsPublicPath: '/',
+ index: path.resolve(__dirname, '../../server/templates/app.html'),
+ assetsRoot: path.resolve(__dirname, '../../server/static/app'),
+ assetsSubDirectory: '',
+ assetsPublicPath: '/static/app',
Here (above) I'm setting where the app.html file and static assets should be created.
Because we're directing Webpack to generate the static assets within Flask's "static" folder (/static/app/)...
html file will automatically be set up correctly by Webpack.
src=/static/app/js/app.f5b53b475d0a8ec9499e.jsstatic/ folder, which Flask assumes has a /static/etc. URL.
app.html file.client/build/webpack.prod.conf.js:
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
- ? 'index.html'
+ ? 'app.html'
: config.build.index,
- template: 'index.html',
+ template: 'app.html',
Here (above) I'm just renaming the 'launch' page, same as in webpack.dev.conf.js.
routes.py:
@web_routes.route('/app')
@login_required
def app():
if current_user.datetime_subscription_valid_until < datetime.datetime.utcnow():
return redirect(url_for('web_routes.pay'))
return render_template('app.html')
Here (above) is my render function. I'm using Flask's Blueprints feature () but you don't have to.