Aller au contenu principal

Pages Guide - Baldr Template

Quick Reference | For comprehensive routing documentation, see ROUTING_GUIDE.md

This is a quick-start guide for creating and managing pages in your Baldr website. For detailed architecture and advanced topics, refer to the complete Routing Guide.


Quick Overview

The Baldr template uses a database-driven routing system where:

  1. Database stores page metadata, SEO, and configuration
  2. Page Registry maps URLs to React components (single source of truth)
  3. Catchall Route handles all dynamic pages automatically
Database Page (/produits) → pageRegistry → React Component → Rendered Page

For the complete architecture, see ROUTING_GUIDE.md → Architecture Overview


Step 1: Create the Page in Admin (Baldr-Bo)

  1. Navigate to SEOPages in your admin panel
  2. Click Create New Page
  3. Fill in the form:
    • Title: Admin reference name (e.g., "About Us")
    • Path: URL path (e.g., /about)
    • Page Type: Select the appropriate type
    • SEO Tab: Add meta title, description, keywords
    • Sitemap Tab: Configure sitemap settings
    • Publication Tab: Set as active when ready

Step 2: Create the Component File

Create a new file in app/pages/ directory:

# Example: For path /about
app/pages/about.page.tsx

Template:

/**
* About Page Component
*
* Mapped to the /about route in the database.
*/

export default function AboutPage() {
return (
<div className="space-y-8">
<section>
<h2 className="text-3xl font-bold mb-4">About Us</h2>
<p className="text-lg text-gray-600">
Your content here...
</p>
</section>

{/* Add more sections as needed */}
</div>
);
}

Step 3: Register in Page Registry

Important: The Page Registry is the single source of truth for routing and sitemap generation.

Update app/config/pageRegistry.ts:

import { lazy } from "react";
import type { PageConfig } from "../config/pageRegistry";

const AboutPage = lazy(() => import("../pages/about.page"));

export const pageRegistry: Record<string, PageConfig> = {
"/": { component: HomePage },

// Add your new page
"/about": {
component: AboutPage
},

// For module pages (that display lists of content)
"/produits": {
component: ProduitsPage,
moduleType: "products" // ← Enables automatic sitemap subpage generation
},
};

About moduleType:

  • Add this ONLY for pages that display module content (products, news, etc.)
  • This automatically generates sitemap subpages (e.g., /produits/product-slug)
  • See ROUTING_GUIDE.md → Module Pages for details

Step 4: Test Your Page

  1. Start the development server: npm run dev
  2. Visit: http://localhost:5173/about
  3. Your component should render with SEO metadata from the database

Component Props

Each page component receives a page prop with metadata:

interface PageProps {
page: {
_id: string;
path: string;
title: string;
seo: {
metaTitle?: string;
metaDescription?: string;
metaKeywords?: string[];
// ... more SEO fields
};
active: boolean;
indexed: boolean;
// ... more fields
};
}

export default function MyPage({ page }: PageProps) {
// Use page metadata if needed
console.log(page.seo.metaTitle);

return <div>...</div>;
}

File Naming Convention

Follow these conventions for consistency:

  • File location: app/pages/
  • File naming: [name].page.tsx
  • Component naming: PascalCase + "Page" suffix

Examples:

app/pages/
├── test.page.tsx → TestPage
├── about.page.tsx → AboutPage
├── contact.page.tsx → ContactPage
├── services.page.tsx → ServicesPage
└── privacy-policy.page.tsx → PrivacyPolicyPage

Nested Routes

For nested routes like /services/web-development:

  1. Database: Create page with path /services/web-development
  2. Component: Create file app/pages/services-web-development.page.tsx
  3. Registry: Register as "/services/web-development": ServicesWebDevelopmentPage

Styling

The template uses Tailwind CSS. Common patterns:

export default function MyPage() {
return (
<div className="space-y-8">
{/* Hero Section */}
<section className="bg-blue-600 text-white rounded-lg p-12">
<h2 className="text-4xl font-bold mb-4">Hero Title</h2>
<p className="text-xl">Hero description</p>
</section>

{/* Content Section */}
<section className="prose prose-lg max-w-none">
<h3>Content Title</h3>
<p>Content goes here...</p>
</section>
</div>
);
}

SEO & Meta Tags

Division of Responsibilities

Database (Managed in Baldr-BO):

  • Meta title, description, keywords
  • Open Graph tags (social sharing)
  • Twitter cards
  • Canonical URLs
  • Indexing directives (robots)
  • Sitemap configuration
  • Scheduled publishing

Component (Developer Code):

  • Page content and structure
  • Layout and styling
  • Interactive elements
  • Client-side functionality

For complete SEO implementation details, see ROUTING_GUIDE.md → SEO & Meta Tags


Module Pages & Sitemap

Module pages display lists of content and automatically generate sitemap subpages.

Example: Products page at /produits

// In pageRegistry.ts
"/produits": {
component: ProduitsPage,
moduleType: "products" // ← Automatically generates /produits/product-slug in sitemap
}

Sitemap will include:

  • /produits (main page)
  • /produits/product-1, /produits/product-2, etc. (individual products)

For complete implementation details, see ROUTING_GUIDE.md → Module Pages


SEO Features

Alternate URLs (hreflang)

For complete hreflang and internationalization documentation, see ROUTING_GUIDE.md → SEO & Meta Tags

Quick Reference:

Alternate URLs tell search engines about different language versions of your page:

English Page (/en/about):

{
{ "lang": "en", "url": "https://mysite.com/en/about" },
{ "lang": "fr", "url": "https://mysite.com/fr/about" },
{ "lang": "es", "url": "https://mysite.com/es/about" },
{ "lang": "x-default", "url": "https://mysite.com/en/about" }
]
}

French Page (/fr/about):

{
"alternateUrls": [
{ "lang": "en", "url": "https://mysite.com/en/about" },
{ "lang": "fr", "url": "https://mysite.com/fr/about" },
{ "lang": "es", "url": "https://mysite.com/es/about" },
{ "lang": "x-default", "url": "https://mysite.com/en/about" }
]
}

Important: Each language version should reference ALL other versions, including itself.

Canonical URLs

Canonical URLs tell search engines which version of a page is the "master" copy when you have duplicate or similar content.

When to use:

  • Multiple URLs showing the same content
  • HTTP vs HTTPS versions
  • With/without www
  • Pagination or filtered content

Example:

Canonical URL: https://example.com/products/item

Renders as:

<link rel="canonical" href="https://example.com/products/item" />

Best Practices

✅ Do:

  • Keep components focused on content and layout
  • Use Tailwind classes for styling
  • Lazy load page components (already configured)
  • Test pages on different screen sizes
  • Use semantic HTML elements

❌ Don't:

  • Put SEO metadata in components (use database)
  • Duplicate SEO data
  • Create huge single-file components
  • Forget to register new pages
  • Hard-code URLs (use Link component)

Component Organization

For larger pages, organize into sections:

// app/pages/about/
├── index.page.tsx // Main component
├── HeroSection.tsx
├── TeamSection.tsx
└── TimelineSection.tsx

// In about/index.page.tsx
import HeroSection from './HeroSection';
import TeamSection from './TeamSection';
import TimelineSection from './TimelineSection';

export default function AboutPage() {
return (
<div className="space-y-12">
<HeroSection />
<TeamSection />
<TimelineSection />
</div>
);
}

Troubleshooting

Page shows "Component Not Found"

  • Check if the component is registered in pageRegistry.ts
  • Verify path in database matches registry key exactly (case-sensitive!)
  • Ensure component file exists and exports default

SEO metadata not showing

  • Verify page is active: true in database
  • Check SEO fields are filled in Baldr-BO
  • Clear browser cache
  • View page source to inspect <head> tags

Module page not generating subpages

  • Verify moduleType is set in pageRegistry
  • Check module items exist in database with active: true
  • Visit /sitemap.xml to verify subpages are included
  • Restart backend server after changes

For more troubleshooting, see ROUTING_GUIDE.md → Troubleshooting


Example: Complete Page Creation

Let's create a "Contact" page:

1. Admin (Baldr-Bo):

Title: Contact Us
Path: /contact
Page Type: standard
SEO Title: Contact Us - Get in Touch
SEO Description: Have questions? Reach out to our team.
Active: ✓

2. Component (app/pages/contact.page.tsx):

export default function ContactPage() {
return (
<div className="space-y-8">
<section>
<h2 className="text-3xl font-bold mb-4">Get in Touch</h2>
<p className="text-gray-600">We'd love to hear from you!</p>
</section>

<section className="bg-white p-8 rounded-lg shadow">
<form className="space-y-4">
<input type="text" placeholder="Name" className="w-full p-3 border rounded" />
<input type="email" placeholder="Email" className="w-full p-3 border rounded" />
<textarea placeholder="Message" className="w-full p-3 border rounded h-32" />
<button className="bg-blue-600 text-white px-6 py-3 rounded">
Send Message
</button>
</form>
</section>
</div>
);
}

3. Registry (app/config/pageRegistry.ts):

const ContactPage = lazy(() => import("../pages/contact.page"));

export const pageRegistry = {
"/test": TestPage,
"/contact": ContactPage, // Add this
};

4. Visit: http://localhost:5173/contact


Happy coding! 🚀