Routing and Pages
Relevant source files
The following files were used as context for generating this wiki page:
The portfolio application is a Single-Page Application (SPA) that utilizes client-side routing to manage navigation between different views or "pages". This is handled by the react-router-dom library, which provides a declarative way to map URL paths to React components. The core of this system is defined in the main App.tsx component, which acts as the central router.
A key architectural feature is the use of lazy loading for all page components. This is implemented with React.lazy() and React.Suspense to improve initial load performance by code-splitting each page into a separate JavaScript chunk. These chunks are only downloaded and parsed when the user navigates to the corresponding route, reducing the initial bundle size and speeding up the first contentful paint.
Core Routing Architecture
The application's routing logic is centralized within the App.tsx component. It wraps the entire application in a ThemeProvider and uses the <Routes> component from react-router-dom to define all possible navigation paths.
Sources: src/app/App.tsx
Component Structure
The main App component establishes the high-level layout, which persists across all pages: a Navbar, a main content area where the routed page is rendered, and a Footer. The ScrollToTop component ensures that navigation to a new page scrolls the user to the top.
The following diagram illustrates the main application component structure.
Sources: src/app/App.tsx:28-32, src/app/App.tsx:90-93
Lazy Loading and Suspense
All page components are loaded asynchronously using React.lazy. While a page component is being fetched, a Suspense component displays a fallback UI. In this application, the fallback is a PageSkeleton containing a PageContentSkeleton, providing a consistent loading state across the application.
This diagram shows the sequence of lazy-loading a page.
Sources: src/app/App.tsx:11-17, src/app/App.tsx:35-42
Route Definitions
The application defines routes for primary pages, utility pages, and a catch-all "Not Found" page.
| Path | Component | Description |
|---|---|---|
/ | Home | The main landing page of the portfolio. |
/about | About | A page detailing information about the author. |
/projects | Projects | A dedicated page showcasing all projects. |
/contact | Contact | A page with contact information or a form. |
/certificates | Certificates | A page to display certificates. |
/privacy | PrivacyPolicy | The privacy policy page. |
* | NotFound | A catch-all route for any undefined paths. |
Sources: src/app/App.tsx:33-88
Page Components
Pages are top-level components within the Feature-Sliced Design (FSD) pages layer. They are responsible for composing widgets and entities to build a complete view for a specific route.
Home Page
The Home page is the main entry point and is composed of several distinct sections, each represented by a widget. This compositional approach allows for clear separation of concerns and reusability.
The structure of the Home page is as follows:
Sources: src/pages/Home.tsx:7-28
Projects Page
The Projects page (/projects) is responsible for displaying a comprehensive list of all projects. It imports projectsData directly and maps over this array to render a vertical list of project details. Each project is displayed in a card-like format with an image, description, tech stack, and links to the live demo and source code.
- Data Source:
projectsDatafrom@/entities/project/model/data. - Layout: A vertical
flexcontainer where each child is a horizontal card for a project. - Interactivity: Each project card contains
<a>tags wrapping<Button>components for navigating to external "Live Demo" and "Source Code" URLs.
Sources: src/pages/Projects.tsx:5-110
Navigation
Navigation is implemented using react-router-dom's declarative linking components, primarily <NavLink> and <Link>, which are used across various widgets.
Navbar Widget
The Navbar is a fixed component at the top of the viewport and provides the primary navigation for the application.
- It uses
NavLinkto create links, which automatically receives anisActiveclass when itshrefmatches the current URL. This is used to style the active link with an underline. - It conditionally renders a "Back to Home" button if the current
location.pathnameis not one of the main paths (/,/about,/projects,/contact). - For mobile viewports (
< 1024px), it renders aBubbleMenucomponent. For larger screens, it displays standard text links.
The main navigation items are defined in an array derived from homeContent.
| Label | Path |
|---|---|
| Home | / |
| About | /about |
| Projects | /projects |
| Contact | /contact |
Sources: src/widgets/Navbar/Navbar.tsx:11-20, src/widgets/Navbar/Navbar.tsx:80-95
Footer Widget
The Footer widget contains secondary navigation links, social media links, and legal information.
- It uses the
Linkcomponent fromreact-router-domfor internal navigation (e.g., to/privacy). - Links are organized into categories: "Explore", "Work", "Socials", and "Legal & Extras".
- On mobile, these sections are presented within an
Accordionfor better space management.
Sources: src/widgets/Footer/Footer.tsx:72-100, src/widgets/Footer/Footer.tsx:313-319
In-Page and Cross-Component Links
Other components also facilitate navigation:
- The
HomeProjectsSectionwidget on the home page includes a "View all projects" link that navigates the user to the/projectspage. - The
Herowidget contains buttons that link to/projectsand/contact.
// Example from HomeProjectsSection.tsx
<Link to="/projects" className="no-underline">
{/* ... */}
</Link>
Sources: src/widgets/HomeProjectsSection/HomeProjectsSection.tsx:28-36, src/widgets/Hero/Hero.tsx:142-152
Deployment Configuration for SPA
For a Single-Page Application, the web server must be configured to handle client-side routes. When a user directly accesses a URL like https://your-site.com/projects, the server must return the main index.html file instead of trying to find a file at /projects. The client-side router then takes over and displays the correct component.
This project uses Netlify for deployment, and this behavior is configured in netlify.toml. The [[redirects]] rule ensures that any request that doesn't match a static file is redirected to index.html with a 200 status code, enabling the React router to function correctly.
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
This configuration is critical for the routing system to work in a production environment.
Sources: netlify.toml:8-11