Adding a New Page
Learn how to add a new page to the Metronic React application.
This guide provides step-by-step instructions for adding a new page to the Metronic React application, from initial creation to testing in the browser.
Overview
Adding a new page to the application involves several steps:
- Creating the page component
- Setting up the routing
- Linking to the page
- Testing the new page
Step 1: Create the Page Component
First, create a new directory for your page component in the appropriate section under src/pages/
:
mkdir -p src/pages/example
Then create the page component file:
// src/pages/example/example-page.tsx
import React from 'react';
import { Helmet } from 'react-helmet-async';
import {
Card,
CardHeader,
CardContent,
CardTitle,
CardDescription
} from '@/components/ui/card';
export function ExamplePage() {
return (
<>
<Helmet>
<title>Example Page | Metronic</title>
</Helmet>
<div className="container mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">Example Page</h1>
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>This is a description of the card.</CardDescription>
</CardHeader>
<CardContent>
<p>This is an example page content.</p>
</CardContent>
</Card>
</div>
</>
);
}
Step 2: Create Index Files (For Exporting)
Create an index file in your page directory to export the component:
// src/pages/example/index.ts
export * from './example-page';
Add an export in the parent index file to make your page section available throughout the app:
// src/pages/index.ts
export * from './example';
export * from './public-profile';
export * from './account';
export * from './dashboards';
export * from './authentication';
export * from './network';
Step 3: Add the Route in the Router Configuration
Add your new page to the routing configuration in src/routing/app-routing-setup.tsx
:
// src/routing/app-routing-setup.tsx
import { ReactElement } from 'react';
import { Navigate, Route, Routes } from 'react-router';
import { DefaultPage } from '@/pages/dashboards';
import { ExamplePage } from '@/pages/example'; // Add this import
const AppRoutingSetup = (): ReactElement => {
return (
<Routes>
<Route element={<RequireAuth />}>
<Route element={<Demo3Layout />}>
<Route path="/" element={<DefaultPage />} />
<Route path="/example" element={<ExamplePage />} /> {/* Add your route */}
{/* Other routes... */}
</Route>
</Route>
</Routes>
);
};
Step 4: Add a Navigation Link
Add your page to the sidebar menu in src/layouts/demo3/components/sidebar-menu.tsx
:
// src/layouts/demo3/components/sidebar-menu.tsx
import {
BarChart3,
FileText, // Add this import
// ... other icons
} from 'lucide-react';
export function SidebarMenu() {
const items: Item[] = [
{
icon: BarChart3,
path: '/',
title: 'Dashboard'
},
{
icon: FileText,
path: '/example',
title: 'Example Page'
},
// ... other items
];
return (
// ... existing render code
);
}
Step 5: Test the New Page
- Start the development server:
npm run dev
- Navigate to your new page:
- With base URL: http://localhost:5173/metronic/tailwind/react/example
- Without base URL (for local testing): http://localhost:5173/example
- Or click the "Example Page" link in the sidebar menu
Important: The application has a base URL configured in
vite.config.ts
as/metronic/tailwind/react
. This means all routes need to be prefixed with this path when accessed directly in the browser. The sidebar menu links will automatically include this prefix.
Working with Protected Routes
All routes inside the <RequireAuth />
wrapper are protected and require authentication. This is handled automatically when you add your route inside the existing protected route structure:
<Route element={<RequireAuth />}>
<Route element={<Demo3Layout />}>
<Route path="/example" element={<ExamplePage />} />
</Route>
</Route>
Creating Pages with Dynamic Routes
For pages that need dynamic parameters:
// src/pages/example/dynamic-page.tsx
import { useParams } from 'react-router-dom';
export function DynamicExamplePage() {
const { id } = useParams();
return (
<div className="container mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">Dynamic Page</h1>
<p>Viewing item with ID: {id}</p>
</div>
);
}
And add a route with a parameter:
// In the AppRoutingSetup component
<Route path="/example/:id" element={<DynamicExamplePage />} />
Best Practices
- Organize Related Pages: Keep related pages in the same directory under
src/pages/
- Follow Naming Conventions:
- Files: Use kebab-case (e.g.,
example-page.tsx
) - Components: Use PascalCase (e.g.,
ExamplePage
)
- Files: Use kebab-case (e.g.,
- Use TypeScript: Take advantage of TypeScript for props and state
- Component Structure:
- Use
Helmet
for page titles - Use the provided UI components from
@/components/ui/
- Keep components focused on one responsibility
- Extract reusable parts into separate components
- Use
- Error Handling: Implement error states and loading indicators where appropriate
Troubleshooting
Page Not Found
- Check if the route is correctly added in
app-routing-setup.tsx
- Ensure the path exactly matches what you're trying to navigate to
- Make sure you're using the correct base URL prefix (
/metronic/tailwind/react
) when accessing directly - Verify that all index files are exporting the component correctly
Component Not Rendering
- Check for JavaScript errors in the browser console
- Verify that all required imports are correct
- Check that the component is properly exported and imported
Layout Issues
- Ensure your page is wrapped in the correct layout component
- Use the provided UI components from
@/components/ui/
- Follow the component documentation for proper usage
Authentication Issues
- For protected routes, make sure the user is authenticated
- Check that the route is correctly wrapped in the
RequireAuth
component