Nxpress LogoNxpressv1.3.8
17

Practical Recipes & Use Cases

Real-world project architectures and complete code patterns showing companion files, templates, route groups, SSG exports, and REST APIs.

1. E-Commerce Store (Dynamic Routes, SEO, Props & Components)

A complete product catalog showcasing dynamic routes, companion data loaders, dynamic SEO metadata, and custom reusable components.

Project Structure
app/
├── layout.ejs              # Global root layout with  and navbar
├── index.ejs               # Store home page
├── index.ts                # Featured products loader
└── products/
    ├── [id].ejs            # Product details view
    └── [id].ts             # Product companion loader & metadata
components/
├── Navbar.ejs              # Reusable navigation bar
└── ProductCard.ejs         # Reusable product card component
nxpress.config.json         # Engine and global configuration
app/products/[id].ts (Companion Data & SEO)
import type { Request, Response, NxpressMetadata } from '@nxpress/core';
import config from '@/nxpress.config.json';

// 1. Dynamic SEO Metadata
export async function metadata(req: Request, res: Response): Promise {
  const siteName = config.globals?.title || 'Nxpress Store';
  return {
    title: `${siteName} - Product #${req.params.id}`,
    description: `Buy product #${req.params.id} at the best price.`,
    openGraph: {
      title: `Product #${req.params.id}`,
      image: `/images/product-${req.params.id}.jpg`
    }
  };
}

// 2. Page Data Loader (Props)
export default async function props(req: Request, res: Response) {
  const { id } = req.params;
  
  // Fetch from database or external API
  const product = {
    id,
    name: `Premium Wireless Headset ${id}`,
    price: 199.99,
    inStock: true,
    features: ['Active Noise Cancelling', '40h Battery', 'Bluetooth 5.3']
  };

  const related = [
    { id: '101', name: 'Protective Case', price: 29.99 },
    { id: '102', name: 'Audio Cable', price: 14.99 }
  ];

  return {
    product,
    related
  };
}
app/products/[id].ejs (Product View Template)
<%= product.name %>

<%= product.name %>

$<%= product.price.toFixed(2) %>

Key Features:

    <% product.features.forEach(function(feat) { %>
  • <%= feat %>
  • <% }); %>

Related Accessories

<% related.forEach(function(item) { %> <% }); %>
components/ProductCard.ejs (Custom Component)

<%= name %>

$<%= price %>

View Details →

2. Multi-Language Blog with Static Site Generation (SSG)

A fast multi-language blog pre-rendering static HTML pages with generateStaticParams, translation dictionaries, and automated export.

Project Structure
app/
├── layout.ejs
└── blog/
    ├── [slug].ejs          # Blog post template with tr() helpers
    └── [slug].ts           # generateStaticParams, props & metadata
locales/
├── en.json                 # English dictionary
└── fr.json                 # French dictionary
nxpress.config.json
locales/en.json & locales/fr.json
// locales/en.json
{
  "blog_title": "Nxpress Engineering Blog",
  "read_time": "{{minutes}} min read",
  "author": "By {{name}}"
}

// locales/fr.json
{
  "blog_title": "Blog d'Ingénierie Nxpress",
  "read_time": "Temps de lecture : {{minutes}} min",
  "author": "Par {{name}}"
}
app/blog/[slug].ts (Static Params, Data & SEO)
import type { Request, Response, NxpressMetadata } from '@nxpress/core';

// 1. Export list of dynamic slugs for Static Site Generation (nxpress export)
export async function generateStaticParams() {
  return [
    { slug: 'announcing-nxpress-v1' },
    { slug: 'file-based-routing-in-depth' },
    { slug: 'mastering-static-export' }
  ];
}

// 2. Dynamic SEO Metadata
export async function metadata(req: Request, res: Response): Promise {
  const { slug } = req.params;
  return {
    title: `Blog - ${slug}`,
    description: `Read the full article about ${slug} on our blog.`
  };
}

// 3. Post Content Loader
export default async function props(req: Request, res: Response) {
  const { slug } = req.params;
  return {
    slug,
    title: slug.replace(/-/g, ' ').toUpperCase(),
    readMinutes: 5,
    authorName: 'Alex Rivers',
    content: 'Nxpress provides an intuitive developer experience with minimal overhead...'
  };
}
app/blog/[slug].ejs (Template with i18n Helpers)
<%= tr('author', { name: authorName }) %> <%= tr('read_time', { minutes: readMinutes }) %>

<%= title %>

<%= content %>

3. Protected Admin Dashboard (Route Groups & Middleware Cascades)

How to use route groups (folder parentheses) to isolate layouts and apply route-group middleware without polluting the URL structure.

Project Structure
app/
├── (auth)/                 # URL: /login (no (auth) in path)
│   ├── login.ejs
│   └── login.ts
└── (dashboard)/            # URL: /overview, /analytics, /settings
    ├── middleware.ts       # Protects all routes inside (dashboard)/
    ├── layout.ejs          # Dashboard shell with sidebar
    ├── overview.ejs
    └── overview.ts
app/(dashboard)/middleware.ts (Directory Auth Guard)
import type { Request, Response, NextFunction } from '@nxpress/core';

export default function authGuard(req: Request, res: Response, next: NextFunction) {
  const sessionToken = req.cookies?.session_token || req.headers['authorization'];

  if (!sessionToken) {
    // Redirect unauthenticated requests to login page
    return res.redirect('/login');
  }

  // Attach authenticated user profile to res.locals
  res.locals.user = { id: 1, name: 'Admin', role: 'admin' };
  next();
}
app/(dashboard)/layout.ejs (Dedicated Dashboard Layout)



  
  Admin Dashboard
  


  
  

  
  

Welcome back, <%= user?.name %>

Logout
<%- body %>

4. Full REST API with Auto-Responses & Status Codes

Building JSON REST APIs using file-based HTTP method exports, cascading API middlewares, and automatic response formatting.

Project Structure
app/
└── api/
    ├── middleware.ts       # Global API middleware (CORS, Rate limiting, Token verify)
    └── users/
        ├── index.ts        # GET /api/users, POST /api/users
        └── [id].ts         # GET /api/users/:id, PUT /api/users/:id, DELETE /api/users/:id
app/api/users/index.ts (List & Create)
import type { Request, Response } from '@nxpress/core';

export const mockUsers = [
  { id: 1, name: 'Alice', email: 'alice@example.com' },
  { id: 2, name: 'Bob', email: 'bob@example.com' }
];

// GET /api/users -> Automatically responds with 200 OK + JSON
export async function GET(req: Request, res: Response) {
  const search = req.query.search as string;
  if (search) {
    return mockUsers.filter(u => u.name.toLowerCase().includes(search.toLowerCase()));
  }
  return mockUsers;
}

// POST /api/users -> Creates new record with 201 Created
export async function POST(req: Request, res: Response) {
  const { name, email } = req.body;
  if (!name || !email) {
    res.status(400);
    return { error: 'Name and email are required' };
  }
  
  const newUser = { id: Date.now(), name, email };
  mockUsers.push(newUser);
  
  res.status(201);
  return newUser;
}
app/api/users/[id].ts (Get, Update, Delete by ID)
import type { Request, Response } from '@nxpress/core';
import { mockUsers } from '.';

// GET /api/users/:id
export async function GET(req: Request, res: Response) {
  const userId = Number(req.params.id);
  const user = mockUsers.find(u => u.id === userId);
  
  if (!user) {
    res.status(404);
    return { error: 'User not found' };
  }
  return user;
}

// PUT /api/users/:id
export async function PUT(req: Request, res: Response) {
  const userId = Number(req.params.id);
  const { name, email } = req.body;
  const user = mockUsers.find(u => u.id === userId);
  
  if (!user) {
    res.status(404);
    return { error: 'User not found' };
  }
  user.name = name ?? user.name;
  user.email = email ?? user.email;
  return { ...user, updatedAt: new Date().toISOString() };
}

// DELETE /api/users/:id
export async function DELETE(req: Request, res: Response) {
  const userId = Number(req.params.id);
  const index = mockUsers.findIndex(u => u.id === userId);
  
  if (index !== -1) {
    mockUsers.splice(index, 1);
  }
  return res.status(204).send();
}