Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements SEO improvements by adding XML sitemap generation and a robots.txt file. The sitemap includes all static pages (home, blog index, likes) and dynamically fetches blog posts from Notion, while robots.txt allows all crawlers and references the sitemap location.
Key changes:
- Added sitemap generation with static pages and dynamic blog posts from Notion
- Added robots.txt configuration allowing all crawlers with sitemap reference
- Added sitemap link to HTML head via layout metadata
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| app/sitemap.ts | Generates sitemap with static pages and blog posts fetched from Notion |
| app/sitemap.test.ts | Comprehensive test coverage for sitemap generation logic |
| app/robots.ts | Configures robots.txt to allow all crawlers and reference sitemap |
| app/robots.test.ts | Test coverage for robots.txt configuration |
| app/layout.tsx | Adds sitemap link to HTML head metadata |
| app/layout.test.tsx | Test coverage for layout metadata including sitemap link |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| const blogPosts: MetadataRoute.Sitemap = posts.map((post) => ({ | ||
| url: `${SITE_URL}${post.slug}/`, | ||
| lastModified: new Date(post.firstPublished), |
There was a problem hiding this comment.
The field name 'firstPublished' suggests the initial publication date, but 'lastModified' typically represents the most recent update. Consider using a 'lastUpdated' or 'lastModified' field from the post data if available, or rename this to 'published' to better reflect that it represents the publication date rather than the last modification date.
app/sitemap.ts
Outdated
|
|
||
| const staticPages: MetadataRoute.Sitemap = [ | ||
| { url: SITE_URL, priority: 1 }, | ||
| { url: `${SITE_URL}blog`, changeFrequency: 'weekly', priority: 0.8 }, |
There was a problem hiding this comment.
The 'blog' URL is missing a trailing slash while 'likes' and blog post URLs include them. This creates inconsistency in URL formatting. For consistency with the trailing slash pattern used elsewhere (line 18), add a trailing slash to the blog URL.
| { url: `${SITE_URL}blog`, changeFrequency: 'weekly', priority: 0.8 }, | |
| { url: `${SITE_URL}blog/`, changeFrequency: 'weekly', priority: 0.8 }, |
Pull Request Review: Add sitemap and robots.txt for SEOThank you for this well-structured PR! The implementation is clean and follows good practices. Here's my detailed review: ✅ Strengths
|
Ensures all page URLs have consistent trailing slash format: - https://michaeluloth.com/ - https://michaeluloth.com/blog/ - https://michaeluloth.com/likes/ - https://michaeluloth.com/slug/
Previously, if fetching blocks failed for any post, the RSS feed would silently skip that post and continue building. This meant we could deploy an incomplete RSS feed without knowing. Now using .unwrap() to crash the build if any post's blocks can't be fetched, ensuring we never deploy a broken RSS feed. Updated test to verify build crashes on block fetch failures.
The <link rel="sitemap"> tag in HTML is: - Not part of the HTML spec - Not used by major search engines - Redundant with robots.txt (which is the standard way to reference sitemaps) Search engines discover sitemaps via robots.txt, manual submission to search consoles, or by crawling /sitemap.xml directly.
Centralizes SITE_URL in utils/constants.ts to ensure consistent trailing slash usage across sitemap, robots.txt, and RSS feed. The trailing slash is critical for URL consistency - all page URLs use trailing slashes (/, /blog/, /likes/, /slug/). Having a single source of truth prevents accidental inconsistencies.
✅ What
/sitemap.xmlwith all static pages and dynamic blog posts from Notion/robots.txtthat allows all crawlers and references the sitemap<head>for search engine discovery🤔 Why