Metronic React
Getting Started

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:

  1. Creating the page component
  2. Setting up the routing
  3. Linking to the page
  4. 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>
  );
};

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

  1. Start the development server:
npm run dev
  1. Navigate to your new page:

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

  1. Organize Related Pages: Keep related pages in the same directory under src/pages/
  2. Follow Naming Conventions:
    • Files: Use kebab-case (e.g., example-page.tsx)
    • Components: Use PascalCase (e.g., ExamplePage)
  3. Use TypeScript: Take advantage of TypeScript for props and state
  4. 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
  5. 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