You can build a Flask application without Next.js, and you can also build a Next.js app without Flask. However, you might find yourself in a situation where you’ve built an application with Flask and later decide to use Next.js for server-side rendering.
So, what do you do at this point?
One thing you can try is to incrementally adopt Next.js or Flask. In this article, I’ll show you how to make Next.js work seamlessly with a Flask API using the Next.js incremental adoption design, and how you can deploy it with Nginx on an Ubuntu server.
To jump ahead in this article:
Build an app in Next.js and Flask
Let’s start by building a sample Next.js application. Following the official Next.js documentation, run the following command to install Next.js on your computer:
npx [email protected]. Follow the instructions to set up a basic app.
This installation will give us a “Hello, World!” app, ready for deployment. If all goes well, you can run
yarn run dev on the terminal and visit
localhost:3000 on your browser to confirm that it works. You should see something like this:
That’s all there is to it for now. Next, let’s build a basic Flask API. I’ll assume you have Python installed, but if you don’t, you can install it by following the instructions in the official documentation for your OS.
More great articles from LogRocket:
First, let’s create and activate a virtual environment to contain the Python application.
python3 -m venv env &amp; source ./env/bin/activate
Next, install Flask by running the following command in your terminal. We’ll use Flask-RESTful to create a restful API:
pip install Flask flask-restful
Then, create a file called
hello.py and add the following code to it:
from flask import Flask from flask_restful import reqparse, Api, Resource app = Flask(__name__) api = Api(app) parser = reqparse.RequestParser() parser.add_argument('task') class Message(Resource): def get(self): return "message": 'Hello World' api.add_resource(Message, '/api/hello') if __name__ == '__main__': app.run(debug=True)
Now, we have both the Flask and the Next.js app set up. Let’s proceed with making them work together.
Integrating Flask API into Next.js using rewrites
Next.js rewrites allow you to map an incoming request path to a different destination path.
Move into the directory of the Next.js app we just created, open the
next.config.js file, and replace the content with the code below:
module.exports = () =&gt; const rewrites = () =&gt; return [ source: "/hello/:path*", destination: "http://localhost:5000/hello/:path*", , ]; ; return rewrites, ; ;
With this integration, we can access all of our API routes directly from Next.js as though the API is in the same domain and port as the Next.js client. This means we’ll only need to call
http://localhost:3000/api/ and that we’ll be able to reach the API at port
Let’s look at an example.
/pages/index.js file and replace its component with the “Hello, World!” component below:
import styles from '../styles/Home.module.css' import useEffect, useState from 'react' export default function Home() const [message, setMessage] = useState(""); const [loading, setLoading] = useState(true); useEffect(() =&gt; fetch('/hello/') .then(res =&gt; res.json()) .then(data =&gt; setMessage(data.message); setLoading(false); ) , ) return ( &lt;div className=styles.container&gt; &lt;p&gt; !loading ? message : "Loading.."&lt;/p&gt; &lt;/div&gt; )
The code above is a simple Next.js component that talks to the Flask API using Fetch. As you can see, we didn’t have to put the exact URL in the call to the API. Next.js understood it based on the settings we initially set.
Of course, you can also choose to call the Flask API directly.
Set up Nginx
Now that we have a working integration, let’s proceed to deployment in Nginx. Install Nginx on your server (an Ubuntu server, in our case), create a config file for your Nginx configuration, which we’ll call
nextflask, and add the following code to the file:
/** /etc/nginx/sites-available/nextflask **/ server server_name yourdomainname.com www.yourdomainname.com; listen 80; location /hello/ proxy_pass http://127.0.0.1:5000/hello/; proxy_http_version 1.1; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location / proxy_pass http://0.0.0.0:3000; proxy_http_version 1.1; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
The Nginx config above will serve your Next.js app on the root domain
yourdomainname.com and serve your API on
After adding this configuration, start Nginx by running the command below:
sudo systemctl start nginx.service
That’s it for setting up Nginx to serve our Flask API and Next.js server. Push your Flask and Next.js code to your server, install the dependencies, and run them separately. Oh, wait, we’ll need to daemonize them.
You can daemonize a Flask app with either Supervisor or Gunicorn, which are two popular tools for deploying Python applications.
We’ll use Gunicorn for Flask and PM2 for Next.js.
Run the Flask API and the Next.js API as a service
Let’s start with running the Flask API with Gunicorn. Ensure that you have a working Python installation on your server, then create a virtual environment to install Gunicorn.
Create a virtual environment:
python3 -m venv env
Then, install Gunicorn and Flask:
pip install gunicorn flask
Set up Gunicorn to serve the Flask application
First, create a
wsgi.py file in the root directory. This will serve as the entry point of the application. Add the following code to the file:
// wsgi.py from hello import app if __name__ == "__main__": app.run()
Next, create config file
sudo vim /etc/systemd/system/hello.service for Gunicorn and add the following configuration to it:
[Unit] Description=Gunicorn instance to serve hello After=network.target [Service] User=eze Group=www-data WorkingDirectory=/path/to/your/app/directory ExecStart=/path/to/gunicorn/bin/gunicorn --workers 3 --bind unix:hello.sock -m 007 wsgi:app [Install] WantedBy=multi-user.target
Pay attention to the reference paths. Finally, start and enable Gunicorn by running the following command in your terminal:
sudo systemctl start hello &amp; sudo systemctl enable hello
To check if the operation was successful, review the status by running the command below:
sudo systemctl status
If all goes well, our Flask app should be up and running on port
500 and in the root domain,
Run the Next.js app with PM2
PM2 is a process management tool for Node.js applications. To use it, install PM2 globally with the following command:
pm2 install -g pm2
Next, run this command in the directory that has your Next.js code:
pm2 start "npm run start" --name nextapp
Your Next.js application will start working on port
3000 and in the root domain,
Congratulations! You have successfully deployed your Next.js frontend with your Flask API. It might seem complicated at first, but you won’t have to repeat this process in your future deployments, because this sets the basic environment for your application to work properly. You might only need to push your code and restart your server, which can be managed by your CI/CD pipeline.
New technologies come and go all the time, and now might be the time for you to choose to deploy Next.js with Flask to improve the general engineering of your application. I hope you find this article helpful.
Personally, I had an old Flask API, but I wanted to continue development with Next.js while retaining some of the Python backend implementations. I found it very easy to switch without interrupting or breaking my existing API.
Check out this sample Next.js project, which you can clone to replicate the process from this article. Cheers!
LogRocket: Full visibility into production Next.js apps
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your Next.js apps — start monitoring for free.