Why
A first-time visitor's impression of the writing is set by whatever happened to be published last, not by the posts that best represent the site. The home page has no way to promote a post, so a strong older piece is buried under whatever is newest.
Current state
app/(home)/page.tsx renders <Summary /> followed by <RecentWriting /> and nothing else. ui/sections/home-recent-writing.tsx renders <PostList limit={5} />, and ui/sections/blog-post-list.tsx:30 fetches all posts sorted by First published descending, then slices the first 5. Of the 37 published blog posts, the home page therefore shows the 5 newest and offers no mechanism to surface anything else.
The Notion Writing data source now has a Featured order number property, populated on three posts:
Featured order |
First published |
Title |
| 1 |
2024-07-29 |
Why unknown types are useful |
| 2 |
2021-05-31 |
Using Slack to report data entry errors to content editors |
| 3 |
2024-12-27 |
Converting a list of JS objects into a parent-child tree |
Every other page reports number: null for the property. No code reads it yet.
Ideal state
- A
Featured Writing section renders above Recent Writing on the home page, using the same h2 treatment and the same date-above-title row markup, so the two sections differ only in their headings.
- The section lists every published blog post whose
Featured order is set, in ascending order of that number.
Featured order behaves as a sort key rather than a position: gaps between values, sets that do not start at 1, and values in any numeric range all render in ascending order with no warning and no error.
- Two posts sharing the same
Featured order render most-recently-published first relative to each other, so the rendered order is deterministic.
Recent Writing shows the 5 most recent published posts that are not already featured above, so no post appears twice on the page.
- The
Featured Writing section, heading included, is absent from the page when no post has a Featured order.
/blog lists every published post, featured ones included, exactly as it does today.
- Changing which posts are featured, or the order they appear in, requires a Notion edit and a redeploy and no code change.
Out of scope
Starting points
ui/sections/home-recent-writing.tsx — the section whose markup and typography the new section matches
io/notion/schemas/post.ts — PostPropertiesSchema and PostListItemSchema, where the new property is parsed at the boundary
app/(home)/page.tsx — where the single getPosts call and the split between featured and recent belong
QA plan
- Run
npm run cache:clear:notion, then npm run dev, and open http://localhost:3000. Expect a Featured Writing heading above Recent Writing, indistinguishable from it in size, weight, colour, and spacing.
- Read the featured rows. Expect exactly three, in this order:
Why unknown types are useful, Using Slack to report data entry errors to content editors, Converting a list of JS objects into a parent-child tree. Note that this is deliberately not date order.
- Read the recent rows. Expect
Converting a list of JS objects into a parent-child tree to be absent, since it is featured above and was previously the second row. Expect 5 rows still, with It's tricky to statically type a "pipe" function in Python now the last of them.
- In Notion, set
Why unknown types are useful to 3 and Converting a list of JS objects into a parent-child tree to 1. Run npm run cache:clear:notion and reload. Expect the featured order to follow the new numbers.
- In Notion, change the three values to
10, 20, and 30. Clear the cache and reload. Expect the same three posts in the same relative order, with no warning in the terminal and no error on the page.
- In Notion, give two featured posts the same number. Clear the cache and reload. Expect both to render, the more recently published one first, and the build to keep working.
- In Notion, clear
Featured order on all three posts. Clear the cache and reload. Expect no Featured Writing heading anywhere on the page, and Recent Writing to show the 5 newest posts including Converting a list of JS objects into a parent-child tree.
- Restore the original values
1, 2, 3 and run npm run build. Expect a clean build, and out/index.html to contain both headings.
- Narrow the browser to 390px. Expect featured rows to stack date above title exactly as the recent rows do.
Done when
The home page renders a Featured Writing section ordered by the Notion Featured order property, and Recent Writing shows only posts not already featured above it.
Depends on
Why
A first-time visitor's impression of the writing is set by whatever happened to be published last, not by the posts that best represent the site. The home page has no way to promote a post, so a strong older piece is buried under whatever is newest.
Current state
app/(home)/page.tsxrenders<Summary />followed by<RecentWriting />and nothing else.ui/sections/home-recent-writing.tsxrenders<PostList limit={5} />, andui/sections/blog-post-list.tsx:30fetches all posts sorted byFirst publisheddescending, then slices the first 5. Of the 37 published blog posts, the home page therefore shows the 5 newest and offers no mechanism to surface anything else.The Notion
Writingdata source now has aFeatured ordernumber property, populated on three posts:Featured orderFirst publishedEvery other page reports
number: nullfor the property. No code reads it yet.Ideal state
Featured Writingsection renders aboveRecent Writingon the home page, using the sameh2treatment and the same date-above-title row markup, so the two sections differ only in their headings.Featured orderis set, in ascending order of that number.Featured orderbehaves as a sort key rather than a position: gaps between values, sets that do not start at 1, and values in any numeric range all render in ascending order with no warning and no error.Featured orderrender most-recently-published first relative to each other, so the rendered order is deterministic.Recent Writingshows the 5 most recent published posts that are not already featured above, so no post appears twice on the page.Featured Writingsection, heading included, is absent from the page when no post has aFeatured order./bloglists every published post, featured ones included, exactly as it does today.Out of scope
npm run deploy:production. Reordering will still need a deploy./blog, the RSS feed, the sitemap, or prev/next post navigation.getPostscall out ofui/layout/header.tsx, tracked in Move getPosts call out of ui/layout/header into the page entry point #59 and Header layout fetches Notion posts directly instead of receiving them as props #155.Starting points
ui/sections/home-recent-writing.tsx— the section whose markup and typography the new section matchesio/notion/schemas/post.ts—PostPropertiesSchemaandPostListItemSchema, where the new property is parsed at the boundaryapp/(home)/page.tsx— where the singlegetPostscall and the split between featured and recent belongQA plan
npm run cache:clear:notion, thennpm run dev, and openhttp://localhost:3000. Expect aFeatured Writingheading aboveRecent Writing, indistinguishable from it in size, weight, colour, and spacing.Why unknown types are useful,Using Slack to report data entry errors to content editors,Converting a list of JS objects into a parent-child tree. Note that this is deliberately not date order.Converting a list of JS objects into a parent-child treeto be absent, since it is featured above and was previously the second row. Expect 5 rows still, withIt's tricky to statically type a "pipe" function in Pythonnow the last of them.Why unknown types are usefulto3andConverting a list of JS objects into a parent-child treeto1. Runnpm run cache:clear:notionand reload. Expect the featured order to follow the new numbers.10,20, and30. Clear the cache and reload. Expect the same three posts in the same relative order, with no warning in the terminal and no error on the page.Featured orderon all three posts. Clear the cache and reload. Expect noFeatured Writingheading anywhere on the page, andRecent Writingto show the 5 newest posts includingConverting a list of JS objects into a parent-child tree.1,2,3and runnpm run build. Expect a clean build, andout/index.htmlto contain both headings.Done when
The home page renders a
Featured Writingsection ordered by the NotionFeatured orderproperty, andRecent Writingshows only posts not already featured above it.Depends on
PostListhas to accept an already-fetchedpostsprop before the home page can render two different lists from a singlegetPostscall.