LogoShipSaaS

Metadata

Learn how to customize metadata for the ShipSaaS template

This document covers the metadata system within the ShipSaaS template and guides you on how to customize SEO settings.

Core Features

The ShipSaaS template has a built-in metadata system that provides:

  • SEO-optimized page titles and descriptions
  • Social media sharing metadata (Open Graph and Twitter Cards)
  • Website icons and application branding (Logo and Favicon)

Understanding the Metadata System

Metadata in ShipSaaS is configured through several key files:

1. Website Configuration

The primary website settings are defined in src/config/website.ts:

src/config/website.ts

import { messages } from '@/messages';

export const websiteConfig: WebsiteConfig = {
  metadata: {
    name: messages.site.name,
    title: messages.site.title,
    description: messages.site.description,
    images: {
      ogImage: '/og.png',
      logoLight: '/logo.webp',
      logoDark: '/logo-dark.png',
    },
  },
  social: {
    github: 'https://github.com/ShipSaaS',
    twitter: 'https://x.com/ShipSaaS',
    youtube: 'https://www.youtube.com/@ShipSaaS',
  },
  // Other configuration sections...
};

This configuration defines:

  • The website's name, title, and description
  • Logo and Open Graph image paths
  • Official account links for social platforms

2. Message Files

Basic website metadata (such as name, title, and description) is defined in message localization files:

messages/en.ts

src/messages/en.ts

export const messages = {
  site: {
    name: 'ShipSaaS',
    title: 'ShipSaaS - The Best SaaS Boilerplate',
    description: 'ShipSaaS is a full-stack SaaS boilerplate...',
  },
  // other messages...
} as const;

messages/zh.ts

src/messages/zh.ts

export const messages = {
  site: {
    name: 'ShipSaaS',
    title: 'ShipSaaS - 快速构建 SaaS 产品',
    description: 'ShipSaaS 是一个使用最先进技术栈构建的 SaaS 模板...',
  },
  // other messages...
} as const;

To switch the currently used language, edit src/messages/index.ts to re-export the target language file.

3. SEO Helper Function

The seo() function in src/lib/seo.ts constructs metadata and canonical links for each page:

src/lib/seo.ts

export function seo(
  path: string,
  options: {
    title: string;
    description?: string;
    keywords?: string;
    image?: string;
    type?: 'website' | 'article';
  }
) {
  const url = getCanonicalUrl(path);
  const image = options.image ?? getOgImage();
  return {
    meta: metadata({ ...options, url, image, type: options.type ?? 'website' }),
    links: [{ rel: 'canonical', href: url }],
  };
}

This function handles:

  • Setting page titles and descriptions
  • Configuring Open Graph and Twitter Card metadata
  • Setting canonical URLs
  • Generating OG image URLs

4. Using SEO in Routes

Each route defines its metadata via the head() function in createFileRoute:

src/routes/index.tsx

import { createFileRoute } from '@tanstack/react-router';
import { seo } from '@/lib/seo';

export const Route = createFileRoute('/')({
  head: () => ({
    ...seo('/', {
      title: 'ShipSaaS - Home',
      description: 'Welcome to ShipSaaS',
    }),
  }),
  component: HomePage,
});

5. Root Layout Metadata

The root route (src/routes/__root.tsx) defines global metadata, including charset, viewport, website icons, and default title/description:

src/routes/__root.tsx

export const Route = createRootRouteWithContext<{
  queryClient: QueryClient;
}>()({
  head: () => ({
    meta: [
      { charSet: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { title: websiteConfig.metadata?.title },
      { name: 'description', content: websiteConfig.metadata?.description },
    ],
    links: [
      { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' },
      { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' },
      { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' },
      { rel: 'icon', href: '/favicon.ico' },
      { rel: 'manifest', href: '/manifest.json' },
    ],
  }),
  // ...
});

Customizing Website Metadata

Basic Website Info

To change basic website information (such as name, title, and description), edit the active language message file:

src/messages/en.ts

export const messages = {
  site: {
    name: 'Your Website Name',
    title: 'Your Website Title - Catchy Tagline',
    description: 'Detailed description of your website for SEO purposes',
  },
  // ...
} as const;

Customizing Social Images

To change the Open Graph image and Logo:

  1. Place your image files in the public directory.
  2. Update the paths in src/config/website.ts:

src/config/website.ts

metadata: {
  // Other settings...
  images: {
    ogImage: '/your-og-image.png',  // For social sharing
    logoLight: '/your-logo-light.png',  // Light mode Logo
    logoDark: '/your-logo-dark.png',  // Dark mode Logo
  },
}

Recommended dimensions:

  • OG Image: 1200×630 pixels for optimal display across social platforms.
  • Logo: At least 512×512 pixels for high-resolution displays.

Update your official social media profile links in the website configuration:

src/config/website.ts

social: {
  github: 'https://github.com/YourUsername',
  twitter: 'https://x.com/YourHandle',
  youtube: 'https://www.youtube.com/@YourChannel',
},

Website Icons and Favicon

To replace the default favicons and app icons:

  1. Generate a complete icon set using tools like Real Favicon Generator.
  2. Place the generated files in the public directory.
  3. The root route will automatically link these files.

Page-Specific Metadata

In each route, use the seo() helper function within head() to define page-specific metadata:

export const Route = createFileRoute('/about')({
  head: () => ({
    ...seo('/about', {
      title: 'About Us',
      description: 'Learn more about our team and mission',
      image: '/images/about-og.png',
    }),
  }),
  component: AboutPage,
});

Blog Post Metadata

Blog posts utilize frontmatter metadata which is applied automatically:

content/blog/example-post.md

---
title: Example Blog Post
description: This is an example blog post with custom metadata
image: https://example.com/images/blog/example-post.png
date: "2024-01-01"
category: tutorial
---

Content here...

Best Practices

  • Keep Titles Concise: Target titles under 60 characters for optimal rendering in search results.
  • Write Descriptive Meta Descriptions: Craft compelling descriptions of 150-160 characters.
  • Use High-Quality Images: Create professional, context-appropriate images for Open Graph and Twitter Cards.
  • Incorporate Keywords Naturally: Naturally integrate relevant keywords in titles and descriptions.
  • Stay Updated: Ensure your metadata updates dynamically along with content revisions.
  • Mobile Optimization: Double-check how your metadata previews look on mobile viewport widths.

Next Steps

Now that you know how to customize metadata in ShipSaaS, explore these related topics:

On this page