2026-06-29
Understanding How This Frontend Portfolio App Works
As a backend engineer, the easiest way to understand a frontend app is to map it to backend concepts you already know.
This portfolio is a Next.js application. You can think of it as a web service where folders define routes, components define reusable response fragments, and content files act like a tiny file-based database.
The Big Picture
- The app is built with Next.js, React, TypeScript, and Tailwind CSS.
- Next.js handles routing, page rendering, static generation, and production builds.
- React is used to describe UI as components.
- TypeScript gives type safety across components and content-loading code.
- Tailwind CSS provides utility classes for styling.
- Blog posts and project writeups are stored as MDX files inside the content folder.
- Vercel builds and deploys the app whenever changes are pushed to the main branch.
Backend Mental Model
If you come from backend systems, this mapping helps:
- app routes are like API route handlers, except they return HTML instead of JSON.
- components are like reusable response builders.
- lib contains shared application logic.
- content is like a small read-only database stored in files.
- public contains static assets served directly.
- next build is like compiling and packaging the service for production.
- Vercel is like the hosting platform and deployment pipeline.
Project Structure
The important folders are:
- app: route definitions and pages.
- components: reusable UI building blocks.
- content: blog posts and project writeups.
- lib: shared data and content-loading logic.
- public: static files such as the resume PDF.
- package.json: scripts, dependencies, and project metadata.
The app Folder
The app folder controls routing.
In this project:
- app/page.tsx becomes the homepage at /.
- app/blog/page.tsx becomes /blog.
- app/blog/[slug]/page.tsx becomes dynamic blog routes like /blog/my-post.
- app/projects/page.tsx becomes /projects.
- app/projects/[slug]/page.tsx becomes dynamic project routes.
- app/about/page.tsx becomes /about.
- app/contact/page.tsx becomes /contact.
- app/experience/page.tsx becomes /experience.
- app/layout.tsx wraps all pages with shared layout and navigation.
- app/globals.css contains global styles.
The routing is file-system based. There is no separate router config file.
Static Routes
A static route is a page with a fixed URL.
Example:
app/about/page.tsxThis creates:
/aboutThis is similar to creating a backend endpoint with a fixed path.
Dynamic Routes
A dynamic route uses brackets in the folder name.
Example:
app/blog/[slug]/page.tsxThis creates URLs such as:
/blog/building-a-personal-portfolio-website
/blog/setting-up-github-ssh-keys-on-macosThe slug is the dynamic value. It works like a path parameter in backend routing.
How Blog Posts Become Pages
Blog posts live in:
content/blogEach post is an MDX file with frontmatter at the top.
Example:
---
title: "My Post"
date: "2026-06-29"
tags: ["Next.js", "Frontend"]
summary: "Short description."
---The filename becomes the URL slug.
Example:
content/blog/my-post.mdxbecomes:
/blog/my-postThe Content Loader
The file lib/content.ts is the content access layer.
It does a few jobs:
- Reads files from content/blog and content/projects.
- Extracts the slug from each filename.
- Parses frontmatter fields like title, date, tags, and summary.
- Returns structured TypeScript objects to the pages.
- Sorts blog posts by date.
From a backend perspective, lib/content.ts is similar to a repository or DAO layer. Instead of querying PostgreSQL, it reads MDX files from disk.
generateStaticParams
Dynamic pages use generateStaticParams.
This tells Next.js which dynamic pages should be generated at build time.
For blog posts, the app reads all blog files and returns their slugs.
Conceptually:
- Read all blog files.
- Extract slugs.
- Generate one static HTML page per slug.
This means the blog is fast because pages are prebuilt during deployment.
Page Rendering
Each page exports a React component.
That component returns JSX, which looks like HTML inside TypeScript.
Example idea:
return <main>...</main>Next.js renders that component into HTML that the browser can display.
For many pages in this portfolio, rendering happens during the build. That is called static generation.
Components
Components are reusable UI pieces.
This project has:
- components/nav.tsx for navigation.
- components/section.tsx for reusable page sections.
- components/cards.tsx for blog and project cards.
- components/markdown.tsx for rendering simple markdown-like content.
From a backend point of view, components are like reusable serializers or template partials. They keep repeated UI patterns in one place.
The Profile Data
The file lib/profile.ts contains structured profile data:
- Name.
- Title.
- Summary.
- Skills.
- Highlights.
- Experience.
Pages import this data and render it. This avoids scattering the same text across many files.
Styling With Tailwind CSS
The UI uses Tailwind CSS classes directly in the markup.
Example classes:
text-slate-950
rounded-lg
border
px-5
py-16Each class maps to a small CSS rule.
This is different from writing large custom CSS files. The benefit is that styling stays close to the component it affects.
The public Folder
The public folder contains static assets.
In this app, the resume PDF lives at:
public/Lokesh_Burma_Resume.pdfAnything in public is served from the site root.
So the resume is available at:
/Lokesh_Burma_Resume.pdfImportant Commands
Use this during development:
pnpm devThis starts the local development server.
Use this before pushing changes:
pnpm buildThis verifies the production build.
Use this to commit and push:
git add .
git commit -m "Add new post"
git pushHow Deployment Works
The deployment flow is:
- Code is pushed to GitHub.
- Vercel detects the push.
- Vercel installs dependencies.
- Vercel runs the build command.
- Next.js generates static pages.
- Vercel publishes the new version.
If the push goes to main, it updates the production website.
How To Add A New Blog Post
- Create a new file in content/blog.
- Add title, date, tags, and summary in frontmatter.
- Write the post body.
- Run pnpm build.
- Commit and push.
- Vercel deploys the new post.
How To Add A New Page
To add a new static page:
- Create a folder under app.
- Add a page.tsx file inside it.
- Export a React component.
Example:
app/uses/page.tsxcreates:
/usesKey Concepts To Understand
- File-based routing: folders under app become URLs.
- Components: reusable pieces of UI.
- Props: data passed into components.
- Static generation: pages are built ahead of time.
- Dynamic routes: bracket folders like [slug] behave like path parameters.
- Frontmatter: metadata at the top of content files.
- Server-side file reads: content is read during build on the server side.
- Public assets: files in public are served directly.
- Deployment pipeline: GitHub push triggers Vercel build.
What This App Is Not Doing Yet
This app is intentionally simple.
It does not currently have:
- A database.
- Authentication.
- API routes.
- A CMS.
- Full MDX rendering with custom React components.
- Syntax highlighting for code blocks.
- Search across blog posts.
Those can be added later if the site grows.
Final Mental Model
Think of this portfolio as a statically generated content service.
The content folder is the data source. The lib folder is the data access layer. The app folder defines routes. Components render reusable UI. Vercel builds the final pages and serves them globally.
Once this model clicks, working on the frontend feels much closer to backend engineering than it first appears.