Skip to content

Pages

This document covers the page system in the ShipSaaS template, how to customize existing pages, and how to create new pages for your specific needs.

The ShipSaaS template contains various page types that you can customize as needed:

  • Custom legal pages (Cookie Policy, Privacy Policy, Terms of Service)
  • Maintenance of changelogs for version releases
  • Creating marketing and informational pages (About, Contact, Waitlist, Roadmap)
  • Adding fully custom pages to fit your specific requirements

Pages in ShipSaaS are organized using TanStack Router’s file-based routing:

Legal page contents are stored in the content/pages directory and rendered via routes in src/routes/(legals)/:

  • Cookie Policy: src/routes/(legals)/cookie.tsx
  • Privacy Policy: src/routes/(legals)/privacy.tsx
  • Terms of Service: src/routes/(legals)/terms.tsx

Release notes are stored in the content/changelog directory and displayed on the changelog page:

  • Changelog: src/routes/(pages)/changelog.tsx — Each release has its own Markdown file.

Marketing pages are rendered via routes under src/routes/(pages)/:

  • About: src/routes/(pages)/about.tsx
  • Contact: src/routes/(pages)/contact.tsx
  • Pricing: src/routes/(pages)/pricing.tsx
  • Waitlist: src/routes/(pages)/waitlist.tsx
  • Roadmap: src/routes/(pages)/roadmap.tsx

Legal pages are written in Markdown format and located in the content/pages directory:

content/pages/privacy.md

---
title: Privacy Policy
description: Our commitment to protecting your privacy and personal data
date: "2025-03-10"
---
## Introduction
Welcome to our Privacy Policy...

To customize a legal page:

  1. Open the corresponding Markdown file in content/pages.
  2. Update the metadata (title, description, date).
  3. Modify the content in Markdown format.
  4. Save the file — the page will update automatically.

Changelogs are stored as Markdown files under content/changelog:

content/changelog/v1.0.0.md

---
title: "Initial Release"
description: "Our first official release with core features"
date: "2024-03-01"
version: "v1.0.0"
published: true
---
### Core Features
- **User Authentication**: Secure login and registration
- **Dashboard**: Intuitive dashboard for managing your projects

To add a new release, create a new Markdown file (e.g., v1.1.0.md) in content/changelog.

For content-heavy pages, add a new Markdown file in content/pages and create the corresponding route:

src/routes/(pages)/faq.tsx

import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/(pages)/faq')({
component: FAQPage,
});
function FAQPage() {
return (
<div className="max-w-4xl mx-auto space-y-8 py-12">
<h1 className="text-3xl font-bold">FAQ</h1>
{/* Your content here */}
</div>
);
}

For pages requiring complex interactivity, create a new route file:

src/routes/(pages)/pricing.tsx

import { createFileRoute } from '@tanstack/react-router';
import { messages } from '@/messages';
import { seo } from '@/lib/seo';
export const Route = createFileRoute('/(pages)/pricing')({
head: () => ({
...seo('pricing', {
title: messages.pricing.title,
description: messages.pricing.description,
}),
}),
component: PricingPage,
});
function PricingPage() {
return (
<div className="max-w-4xl mx-auto space-y-8">
<h1 className="text-center text-3xl font-bold">
{messages.pricing.title}
</h1>
{/* Pricing components */}
</div>
);
}

Routing constants are defined in src/lib/routes.ts:

src/lib/routes.ts

export const Routes = {
Root: '/',
Login: '/auth/login',
Register: '/auth/register',
Dashboard: '/dashboard',
Settings: '/settings',
// ...
};

ShipSaaS uses middleware to protect routes. Interfaces like the user dashboard and settings are protected using the authRouteMiddleware defined under src/middlewares/. Administrative interfaces are protected via adminRouteMiddleware:

src/routes/dashboard.tsx

import { createFileRoute } from '@tanstack/react-router';
import { authRouteMiddleware } from '@/middlewares/auth-middleware';
export const Route = createFileRoute('/dashboard')({
beforeLoad: ({ context }) => authRouteMiddleware(context),
component: DashboardLayout,
});