How to build frontend on Flask view directly
Tags: webdev, flask, python, javascript
Published: 2022-08-11 21:34:00

In the past, when I first learned Flask to create an Instagram clone, I used Flask to purely create the backend. That meaning I created a bunch of api endpoints on Flask so that I could fetch them from my frontend, at the time, React.
And yes, Flask is mainly used for backend development. However, in Flask, we usually create templates that are html files. If my application does not require a huge frontend and if I want to build my frontend directly on the view, wouldn't that be great?

For those who are not familiar with Flask, [Flask](https://flask.palletsprojects.com/en/2.2.x/) is a micro web framework written in Python. Flask is popular over other python-based web libraries/frameworks since it is very light and the users can create a webapp with just a single page of code. I am not getting into what Flask is in this article--you can find great blog posts online to see how powerful Flask is.

## So, How?
**Setup**
So, this is how your simple Flask app would look like.
```
> Folder (Flask App)
 > templates 
  > index.html
 > app.py
```
The templates folder includes the `index.html` file, which is view for the Flask app. This is equivalent to the `view` folder in Express. Technically, you're done setting up, since you can just write a bunch of html in your `index.html` file. However, we all know that pure html is not the way to go.
If you want to add JavaScript in your `index.html`, then create a folder called `static` in your root directory.

Your final Flask app should look like this. 
```
> Folder (Flask App)
 > static
 > templates 
  > index.html
 > app.py
```
**Add JavaScript** 
Now, we are going to add some JavaScript files inside the `static` folder. Let's first start by adding one JavaScript file called `main.js` as such.
```
> Folder (Flask App)
 > static
  > main.js
 > templates 
  > index.html
 > app.py
```
Now, open your `index.html` file. I will assume that you have only the bare skeleton html. 
```html
<!DOCTYPE html>
<html>
<head>
    <title>Flask App!</title>
</head>

<body>
</body>
</html>
```
You would normally add a JavaScript file by using the `<script>` tags as such.
```html
<script type='text/javascript' src='main.js'></script>
```
In your Flask app, that is not possible. However, there is a very simple fix. Assuming that you have your `main.js` in your `static` folder, embed the following code in your `src` attribute of the `<script>` tag.
```html
src={{ url_for('static', filename='main.js') }}
```
Your final `index.html` will look like this.
```html
<!DOCTYPE html>
<html>
<head>
    <title>Flask App!</title>
</head>

<body>

...

<script type='text/javascript' src={{ url_for('static', filename='main.js') }}></script>
</body>
</html>
```
Great! But how about multiple JavaScript files?
That's when bundling comes into play.
**JavaScript Bundling**
In the user's perspective, having multiple JavaScript files for different functionalities is preferred. But from the DOM's perspective, it doesn't care. Rather, it is preferred to render one JavaScript file over multiple JavaScript files. Thus, we will bundle all of our JavaScript files together and pass in one `main.js` file to our `index.html`.

First, install `flask_assets` on your command line.
```
pip install flask_assets
```
Next, in your Flask app, in this case `app.py`, import `Bundle` and `Environment`.
```python
from flask_assets import Bundle, Environment
```
We will assume that we have the following folder structure. We have three JavaScript files that we want to bundle up.
```
> Folder (Flask App)
 > static
  > file1.js
  > file2.js
  > file3.js
 > templates 
  > index.html
 > app.py
```
Now, create a bundle of our JavaScript files.
``` python
# your imports
...

app = Flask(__name__)

files = Bundle('file1.js', 'file2.js', 'file3.js', output = 'gen/main.js')
```
Next, create an `assets` variable that creates an environment of our app and register it.
```py
...

files = Bundle('file1.js', 'file2.js', 'file3.js', output = 'gen/main.js')
assets = Environment(app)
assets.register('main_js', js)
```
That's it for our `app.py`.

Navigate to your `index.html' and add the following code.
![assets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d5qnpux23eazcke8xavh.jpg)


And that's it!
You would have noticed that you have a new directory called `gen` that has your JavaScript bundle or `main.js` for us.
Bundling CSS is analogous as well, so if you need to pass in multiple css files to your `index.html`, follow the steps above again.

Hope this helps, and happy webdev!