Serving Flutter Web Applications With Python-Flask | by Ajiri Gunn | Apr, 2022

There’ll be bugs preying on your every misstep so do well to not ignore the literature.

Serving Flutter web apps on private servers takes a bit of effort. The issue is that when you launch the popular index.html file of a flutter web build, flutter renders your UI by running code in the main.dart.js and flutter_service_worker.js files — these files are somewhere in your file tree.

Flutter also requires data from other asset files (images, fonts, manifests etc.) to properly render your application and those are somewhere else in the file tree. The challenge is to serve these files to Flutter whenever they are requested over HTTP during the Flutter rendering process.

The reason just stated is why nothing usually happens when you launch the index.html file of a Flutter web build on a browser — there’s no API to serve the required files.

We would now be building a Flask project that serves a Flutter web application with the required files as they are requested by Flutter.

This article assumes that you are familiar with Flask and Flutter web applications. You should be able to follow along even if you’re only a bit familiar.

We would be following these 4 steps.

  1. Build Flutter web application.
  2. Modify build files for Flask API.
  3. Build and configure Flask application.
  4. Code REST API to serve Flutter applications.

In any case, ensure that your Flask app fulfils the requirements of steps 2 and 4.

Feel free to skip this step if you can generate and locate your Flutter web build files.

My editor of choice is the brilliant android studio. You could also use VSCode of course. We’ll build a Flutter application so create one and call it flask_ui_app (or what you want — you know the drill). Do not forget to enable web support if you use the android studio.

Enabling web support with android studio.

In the event that you create a project without web support, you can add it via terminal by entering the following command.

> flutter create .

Where the terminal directory is set to the root of your current Flutter project.

You should now see the web folder in the project tree.

Web enabled flutter application

Now run your Flutter web application to be sure it safely loads up the default counter application.

Default flutter counter application.

And now we can proceed to build our release files.

With the root folder of your command terminal set to that of the current Flutter project, build the web application by entering the following command.

> flutter build web --release -v

After the build, you can find the web release files in the path[project_root]/build/web/. We’ll be needing all the files in that folder.

Web build folder with release files

This step requires only that the index.html file in the web build folder be modified by replacing the line:

<base href="/">

with

<base href="/web/">

You will soon see that ‘web’ can be replaced with another term such as ‘app’ as long as they correspond with the API routes.

It’s important to repeat this step whenever you update your Flutter web build.

If you’re already working with a Flask application or you know how to create a simple Flask app, you can open up your Flask project and skip this step.

Here we can simply generate a Flask application using pip. To follow along with this step, you need to have Python, pip, and virtualenv installed on your system. You can follow these guides if you do not have them installed.

  • Python installation guide.
  • Pip installation guide.
  • Virtualenv installation guide.

Now create an empty project folder and give it a name- mine is flask_flutter_app. Navigate to the folder directory in your command terminal.

> cd [path to new project]

First, we would be creating a virtual environment in this folder as is recommended for Python projects. You can do this by running the following command in your command terminal window.

> python -m venv env

Next, we’ll activate the Python virtual environment by running the following command in the terminal for Linux/mac users.

> source env/bin/activate

If on a windows system, you’ll have to run this instead.

> .envScriptsactivate

Your terminal window should now indicate that your virtual environment is active.

(env)> 

Next, we’ll install Flask in the virtual environment by running the following command.


(env)> pip install flask

On to coding. We’ll be using a Python file named app.py so create one in the project root folder, open this file in your favorite code editor and paste the following setup code.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def say_hello():
return ('Hello world')

if __name__ == '__main__':
app.run()

The code snippet should look familiar and it’s really a very basic Flask application.

We can test the app by running the following command in the terminal.

> flask run

At this point, the result should contain something like this.


* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

And if launching the url http://127.0.0.1:5000/ in your browser shows a ‘hello world’ text, then we’re good to go.

Now, the fun begins. First thing to do is copy all the files in your Flutter web build directory from step 1 to a new directory which we would name ‘templates’. Your Flask project file tree should now look like this:

Flask Project Structure

Flask takes a special note of files in the templates directory. That directory is where Flask would look when an API requests a web page from the Flask application using the built-in Flask method render_template.

However, the default templates directory can be changed when instantiating the Flask app as shown in the following code snippet.

# Optional - not for this step
app = Flask(__name__, template_folder='web')

All we now need to do is write API functions that would return document files in the Flutter web build folder using the built-in Flask send_from_directory method.

First, add the following import statements to the top of your app.py file.

from flask import Flask
from flask import send_from_directory
from flask import render_template

Next, copy and paste this code into your Flask application.

FLUTTER_WEB_APP = 'templates'

@app.route('/web/')
def render_page_web():
return render_template('index.html')

@app.route('/web/<path:name>')
def return_flutter_doc(name):

datalist = str(name).split('/')
DIR_NAME = FLUTTER_WEB_APP

if len(datalist) > 1:
for i in range(0, len(datalist) - 1):
DIR_NAME += '/' + datalist[i]

return send_from_directory(DIR_NAME, datalist[-1])

You’ll notice the render_page_web function is attached to the web route so the next time you run your Flask application, you’ll be able to launch the Flutter app from the url [local_host]/web .

I took my app a simple step further and replaced the home route with the same rendering code — now the Flutter app is the home page of my Flask application.

@app.route('/')
def render_page():
return render_template('/index.html')

If you run the Flask app at this point, you’ll see the documents requested by Flutter after launching the index.html page using the [local_host]/web url and the url pattern for these requests.

Flask logs showing flutter requests to fetch build files.

You’ll notice that the path to the requested files in the templates directory is embedded in the URL of the request. Hence, the return_flutter_doc function extracts the path to the requested files from the request URL and serves the files from the templates folder over HTTP.

Find all the code on this GitHub Repository.

If you get the logic, you should be able to conveniently serve your Flutter web apps with any backend framework of your familiarity.

Leave a Comment