SEO Configuration
The Ellemment Stack provides comprehensive SEO support through Remix's built-in meta tag system and additional resource routes for essential SEO files.
Meta Tags
Configure meta tags on a per-route basis using Remix's meta system:
// routes/about.tsx import type { V2_MetaFunction } from '@remix-run/node'
export const meta: V2_MetaFunction = () => { return [ { title: 'About Us' }, { name: 'description', content: 'Learn about our company' }, { property: 'og:title', content: 'About Us' }, { property: 'og:description', content: 'Learn about our company' }, ] }
Sitemap Generation
The stack integrates @nasa-gcn/remix-seo
for sitemap handling.
Dynamic Sitemap Entries
// routes/blog/_layout.tsx import { type SEOHandle } from '@nasa-gcn/remix-seo' import { serverOnly$ } from 'vite-env-only/macros' ,[object Object], ,[object Object],
}), }
Excluding Routes
Exclude routes from the sitemap:
// routes/admin/dashboard.tsx import { type SEOHandle } from '@nasa-gcn/remix-seo'
export const handle: SEOHandle = { getSitemapEntries: () => null, }
Server-Side Generation
The sitemap generator uses vite-env-only/macros
to ensure server-only code execution:
// routes/products.tsx import { serverOnly$ } from 'vite-env-only/macros' ,[object Object], ,[object Object],
}) }
Best Practices
Meta Tag Guidelines
- Page-Specific Content:
export const meta: V2_MetaFunction = ({ data }) => { const { product } = data return [ { title: product.name }, { name: 'description', content: product.description }, { name: 'keywords', content: product.tags.join(', ') } ] }
- Dynamic Open Graph:
export const meta: V2_MetaFunction = ({ data, location }) => { return [ { property: 'og:url', content: `https://yourdomain.com${location.pathname}` }, { property: 'og:image', content: data.imageUrl } ] }
Sitemap Optimization
- Priority Setting:
const getPriority = (route: string) => { if (route === '/') return 1.0 if (route.startsWith('/products')) return 0.8 if (route.startsWith('/blog')) return 0.7 return 0.5 }
- Change Frequency:
const getChangeFreq = (route: string) => { if (route === '/products') return 'daily' if (route.startsWith('/blog')) return 'weekly' return 'monthly' }
Implementation Guide
Setup Resource Routes
- Create Robots.txt:
// routes/robots[.]txt.ts import { generateRobotsTxt } from '@nasa-gcn/remix-seo'
export function loader() { return generateRobotsTxt([ { type: 'sitemap', value: ',[object Object],' }, { type: 'userAgent', value: '*' }, { type: 'allow', value: '/' }, { type: 'disallow', value: '/admin' } ]) }
- Configure Sitemap:
// routes/sitemap[.]xml.ts import { generateSitemap } from '@nasa-gcn/remix-seo'
export function loader() { return generateSitemap(request, manifest, { siteUrl: ',[object Object],', headers: { 'Cache-Control': 'public, max-age=3600' } }) }
For more information about deployment configuration, see the deployment documentation.