🌳 C:\Users\soura\Documents\mine\fastapi\blog
├── 📁 alembic
├── 📁 apis
| └── 📁 v1
├── 📁 apps
| └── 📁 v1
├── 📁 core
├── 📁 database
├── 📄 docker-compose.yaml
├── 📄 Dockerfile
├── 📄 main.py
├── 📄 requirements.txt
├── 📁 schemas
├── 📁 static #new
| └── 📁 images
└── 📁 templates
├── 📄 base.html
├── 📁 blog
└── 📁 components
Time to make our FastAPI app look less like a backend API and more like a real web application! Today we're setting up static file serving and creating a clean navigation bar that doesn't make users feel our website is scrappy.
First things first, let's get our requirements.txt. aiofiles
is crucial for serving static files efficiently in an async environment.
fastapi==0.115.12
uvicorn==0.27.1
python-dotenv==1.1.1
psycopg2-binary==2.9.10
sqlmodel==0.0.24
alembic==1.16.4
PyJWT==2.10.1
python-multipart==0.0.20
Jinja2==3.1.6
aiofiles==24.1.0
Your FastAPI app needs to serve CSS, JavaScript, images, and all those files that make your app not look like it's from 1995. Here's how we set it up in our main application file:
from fastapi import FastAPI
from typing import Dict
from sqlalchemy import text
from core.config import settings
from apis.deps import get_db
from apis.main import api_router
from apps.main import app_router
from fastapi.staticfiles import StaticFiles
app: FastAPI = FastAPI(title=settings.TITLE, description=settings.DESCRIPTION, version=settings.VERSION)
app.include_router(api_router)
app.include_router(app_router)
app.mount("/static", StaticFiles(directory="static"), name="static")
That app.mount()
line is doing the heavy lifting. It tells FastAPI: "Hey, whenever someone requests /static/something
, go look in the static/
directory and serve up that file."
Now for the fun part - a navigation bar that actually looks modern. I'm using Tailwind CSS here because life's too short for writing custom CSS from scratch. Let's add the below url_for line in the navbar.html wrapped inside the anchor tag.
<nav class="bg-white shadow-md border-b border-gray-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<!-- Left side - Blogs link -->
<div class="flex items-center">
<!-- Logo Image in a link -->
<a href="/">
<img src="{{ url_for('static', path='images/flash.png') }}" alt="" width="30" height="24" class="mx-4">
</a>
<a href="/blogs" class="text-emerald-500 hover:text-emerald-600 font-medium text-lg transition duration-200">
Blogs
</a>
</div>