Flask: Integrating with React/Vue.js
Integrating Flask with modern JavaScript frameworks like React or Vue.js enables developers to build dynamic, responsive web applications with a robust backend. Built on Flask’s lightweight core and leveraging Jinja2 Templating and Werkzeug WSGI, Flask serves as an API backend, while React or Vue.js handles the frontend. This tutorial explores Flask integrating with React/Vue.js, covering setup, API communication, and practical applications for full-stack development.
01. Why Integrate Flask with React/Vue.js?
Flask provides a flexible backend for creating RESTful APIs, handling authentication, and managing data, while React and Vue.js excel at building interactive, component-based user interfaces. Combining them allows developers to separate concerns, leveraging Flask’s simplicity for server-side logic and the reactivity of React/Vue.js for client-side rendering. This integration, supported by Jinja2 Templating and Werkzeug WSGI, ensures scalability and maintainability for modern web applications.
Example: Basic Flask API Setup
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/data')
def get_data():
return jsonify({'message': 'Hello from Flask!', 'data': [1, 2, 3]})
if __name__ == '__main__':
app.run(debug=True)
Output (visiting /api/data):
{
"message": "Hello from Flask!",
"data": [1, 2, 3]
}
Explanation:
Flask- Serves as the backend API.jsonify- Returns JSON responses for frontend consumption.
02. Key Integration Techniques
Integrating Flask with React or Vue.js involves setting up a Flask API, serving the frontend, and enabling communication via HTTP requests. The table below summarizes key techniques and their applications:
| Technique | Description | Use Case |
|---|---|---|
| RESTful API | @app.route, jsonify |
Expose backend data to frontend |
| Frontend Setup | React/Vue.js with create-react-app or vue create |
Build interactive UI |
| HTTP Requests | fetch or axios |
Communicate between frontend and backend |
| CORS Handling | Flask-CORS |
Enable cross-origin requests |
| Static File Serving | app.static_folder |
Serve compiled frontend assets |
2.1 Creating a RESTful API with Flask
Example: Flask API for Tasks
from flask import Flask, jsonify, request
app = Flask(__name__)
tasks = [
{'id': 1, 'title': 'Learn Flask', 'done': False},
{'id': 2, 'title': 'Learn React', 'done': False}
]
@app.route('/api/tasks', methods=['GET'])
def get_tasks():
return jsonify(tasks)
@app.route('/api/tasks', methods=['POST'])
def add_task():
task = request.get_json()
tasks.append(task)
return jsonify(task), 201
if __name__ == '__main__':
app.run(debug=True)
Output (GET /api/tasks):
[
{"id": 1, "title": "Learn Flask", "done": false},
{"id": 2, "title": "Learn React", "done": false}
]
Explanation:
GET- Retrieves all tasks.POST- Adds a new task to the list.
2.2 Setting Up React Frontend
Example: React App Fetching Data
// src/App.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [tasks, setTasks] = useState([]);
useEffect(() => {
axios.get('http://localhost:5000/api/tasks')
.then(response => setTasks(response.data))
.catch(error => console.error('Error fetching tasks:', error));
}, []);
return (
<div>
<h1>Tasks</h1>
<ul style="padding: 0px 0px 0px 20px; margin-top: 0px;">
{tasks.map(task => (
<li key={task.id}>{task.title}</li>
))}
</ul>
</div>
);
}
export default App;
Setup Commands:
npx create-react-app my-app
cd my-app
npm install axios
npm start
Explanation:
axios.get- Fetches tasks from the Flask API.useEffect- Loads data on component mount.
2.3 Setting Up Vue.js Frontend
Example: Vue.js App Fetching Data
// src/App.vue
<template>
<div>
<h1>Tasks</h1>
<ul style="padding: 0px 0px 0px 20px; margin-top: 0px;">
<li v-for="task in tasks" :key="task.id">{{ task.title }}</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
tasks: []
};
},
async created() {
try {
const response = await axios.get('http://localhost:5000/api/tasks');
this.tasks = response.data;
} catch (error) {
console.error('Error fetching tasks:', error);
}
}
};
</script>
Setup Commands:
vue create my-app
cd my-app
npm install axios
npm run serve
Explanation:
axios.get- Retrieves tasks from Flask.created- Fetches data when the component is created.
2.4 Handling CORS with Flask-CORS
Example: Enabling CORS
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # Enable CORS for all routes
@app.route('/api/data')
def get_data():
return jsonify({'message': 'CORS-enabled data'})
if __name__ == '__main__':
app.run(debug=True)
Output (React/Vue fetching /api/data):
{
"message": "CORS-enabled data"
}
Explanation:
Flask-CORS- Allows cross-origin requests from frontend (e.g., localhost:3000).- Prevents CORS errors during development.
2.5 Serving Frontend from Flask
Example: Serving React Build
from flask import Flask, send_from_directory
import os
app = Flask(__name__, static_folder='frontend/build', static_url_path='/')
@app.route('/')
def serve():
return send_from_directory(app.static_folder, 'index.html')
@app.route('/api/data')
def get_data():
return {'message': 'Data from Flask'}
if __name__ == '__main__':
app.run(debug=True)
Setup Commands (React):
cd frontend
npm run build
mv build ../frontend/build
Explanation:
static_folder- Points to the compiled frontend build.send_from_directory- Serves the React/Vue.js application.
2.6 Incorrect Integration
Example: Missing CORS Configuration
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/data')
def get_data():
return jsonify({'message': 'No CORS'})
if __name__ == '__main__':
app.run(debug=True)
Output (React fetching /api/data):
Access to XMLHttpRequest at 'http://localhost:5000/api/data' from origin 'http://localhost:3000' has been blocked by CORS policy
Explanation:
- Missing CORS configuration blocks frontend requests.
- Solution: Install and use
Flask-CORS.
03. Effective Usage
3.1 Recommended Practices
- Use
Flask-CORSduring development and configure specific origins in production.
Example: Comprehensive Integration
from flask import Flask, jsonify, request
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
tasks = [
{'id': 1, 'title': 'Learn Flask', 'done': False}
]
@app.route('/api/tasks', methods=['GET', 'POST'])
def tasks_endpoint():
if request.method == 'GET':
return jsonify(tasks)
elif request.method == 'POST':
task = request.get_json()
tasks.append(task)
return jsonify(task), 201
if __name__ == '__main__':
app.run(debug=True)
React Frontend (App.js):
// src/App.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [tasks, setTasks] = useState([]);
const [newTask, setNewTask] = useState('');
useEffect(() => {
axios.get('http://localhost:5000/api/tasks')
.then(response => setTasks(response.data));
}, []);
const addTask = () => {
axios.post('http://localhost:5000/api/tasks', {
id: tasks.length + 1,
title: newTask,
done: false
}).then(response => {
setTasks([...tasks, response.data]);
setNewTask('');
});
};
return (
<div>
<h1>Task Manager</h1>
<input
value={newTask}
onChange={e => setNewTask(e.target.value)}
placeholder="New task"
/>
<button onClick={addTask}>Add Task</button>
<ul style="padding: 0px 0px 0px 20px; margin-top: 0px;">
{tasks.map(task => (
<li key={task.id}>{task.title}</li>
))}
</ul>
</div>
);
}
export default App;
- Use
axiosorfetchfor reliable API calls. - Structure Flask APIs with clear endpoints and methods.
3.2 Practices to Avoid
- Avoid serving frontend and backend on the same port during development without CORS.
Example: Incorrect API Endpoint
from flask import Flask
app = Flask(__name__)
@app.route('/data') # Incorrect: Non-API route
def get_data():
return "Plain text response"
if __name__ == '__main__':
app.run(debug=True)
Output (React fetching /data):
SyntaxError: Unexpected token P in JSON at position 0
- Non-JSON responses break frontend parsing.
- Solution: Use
jsonifyfor API endpoints.
04. Common Use Cases
4.1 Task Management Application
Build a task manager with Flask backend and React/Vue.js frontend.
Example: Task Manager
from flask import Flask, jsonify, request
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
tasks = [
{'id': 1, 'title': 'Initial Task', 'done': False}
]
@app.route('/api/tasks', methods=['GET', 'POST'])
def manage_tasks():
if request.method == 'GET':
return jsonify(tasks)
elif request.method == 'POST':
task = request.get_json()
tasks.append(task)
return jsonify(task), 201
if __name__ == '__main__':
app.run(debug=True)
Vue.js Frontend (App.vue):
// src/App.vue
<template>
<div>
<h1>Task Manager</h1>
<input v-model="newTask" placeholder="New task" />
<button @click="addTask">Add Task</button>
<ul style="padding: 0px 0px 0px 20px; margin-top: 0px;">
<li v-for="task in tasks" :key="task.id">{{ task.title }}</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
tasks: [],
newTask: ''
};
},
async created() {
const response = await axios.get('http://localhost:5000/api/tasks');
this.tasks = response.data;
},
methods: {
async addTask() {
const task = { id: this.tasks.length + 1, title: this.newTask, done: false };
const response = await axios.post('http://localhost:5000/api/tasks', task);
this.tasks.push(response.data);
this.newTask = '';
}
}
};
</script>
Explanation:
- Flask handles task storage and API logic.
- Vue.js provides a reactive frontend for task management.
4.2 User Dashboard
Create a user dashboard with Flask API and React frontend.
Example: User Dashboard
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
users = [
{'id': 1, 'name': 'Alice', 'email': 'alice@example.com'}
]
@app.route('/api/users')
def get_users():
return jsonify(users)
if __name__ == '__main__':
app.run(debug=True)
React Frontend (App.js):
// src/App.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [users, setUsers] = useState([]);
useEffect(() => {
axios.get('http://localhost:5000/api/users')
.then(response => setUsers(response.data));
}, []);
return (
<div>
<h1>User Dashboard</h1>
<table class="article-table-container">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{users.map(user => (
<tr key={user.id}>
<td>{user.name}</td>
<td>{user.email}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default App;
Explanation:
- Flask serves user data via API.
- React displays data in a tabular, responsive format.
Conclusion
Integrating Flask with React or Vue.js, powered by Jinja2 Templating and Werkzeug WSGI, enables the creation of modern, full-stack web applications. Key takeaways:
- Use Flask to build RESTful APIs with
jsonify. - Leverage React/Vue.js for dynamic, component-based frontends.
- Enable CORS with
Flask-CORSfor seamless communication. - Avoid common pitfalls like missing CORS or incorrect response formats.
With this integration, you can build scalable, interactive web applications that combine the strengths of Flask’s backend and React/Vue.js’s frontend capabilities!
Comments
Post a Comment