diff --git a/examples/social-feed/src/components/Article.astro b/examples/social-feed/src/components/Article.astro
index 2febb34fe..0b0829412 100644
--- a/examples/social-feed/src/components/Article.astro
+++ b/examples/social-feed/src/components/Article.astro
@@ -1,7 +1,5 @@
 ---
 import ArticleHeader from './ArticleHeader.astro';
-import Icon from './Icon.astro';
-import Prose from './Prose.astro';
 import SplitLayout from './SplitLayout.astro';
 import type { Article, Post } from '../content/config.js';
 
@@ -17,7 +15,7 @@ const { Content, headings } = await article.render();
 <article>
 	<ArticleHeader {article} class="header" />
 	<SplitLayout reverse>
-		<div class="p-content">
+		<div class="e-content">
 			<Content />
 		</div>
 
@@ -46,11 +44,11 @@ const { Content, headings } = await article.render();
 		padding-block: var(--theme-space-md);
 	}
 
-	.p-content > :global(* + *) {
+	.e-content > :global(* + *) {
 		margin-block-start: 1em;
 	}
 
-	.p-content > :global(p:first-child::first-letter) {
+	.e-content > :global(p:first-child::first-letter) {
 		float: left;
 		font-size: 3.5rem;
 		padding-inline-end: 0.5rem;
@@ -58,7 +56,7 @@ const { Content, headings } = await article.render();
 		font-weight: bold;
 	}
 
-	.p-content :global(img, video, figure) {
+	.e-content :global(img, video, figure) {
 		margin-inline: auto;
 	}
 
@@ -86,7 +84,7 @@ const { Content, headings } = await article.render();
 			display: block;
 		}
 
-		.p-content > :global(* + *) {
+		.e-content > :global(* + *) {
 			margin-block-start: 1.5em;
 		}
 	}
diff --git a/examples/social-feed/src/components/ArticleHeader.astro b/examples/social-feed/src/components/ArticleHeader.astro
index 27ada323e..9830a763e 100644
--- a/examples/social-feed/src/components/ArticleHeader.astro
+++ b/examples/social-feed/src/components/ArticleHeader.astro
@@ -21,19 +21,19 @@ const { text: readingTime } = await getReadingTime(article.body);
 	<div class="cover">
 		{
 			article.data.cover && (
-				<Image src={article.data.cover.src} alt={article.data.cover.alt} />
+				<Image src={article.data.cover.src} alt={article.data.cover.alt} class="u-photo" />
 			)
 		}
 
-		<div class="author">
-			<Image src={settings.avatar.src} alt={settings.avatar.alt} width={80} />
-			<p class="u-name">{settings.name}</p>
-			<p class="u-nickname">{settings.username}</p>
+		<div class="p-author h-card">
+			<Image src={settings.avatar.src} alt={settings.avatar.alt} width={80} class="u-photo" />
+			<p class="p-name">{settings.name}</p>
+			<p class="p-nickname">{settings.username}</p>
 		</div>
 	</div>
 
 	<div class="meta">
-		<FormattedDate date={article.data.pubDate} />
+		<FormattedDate date={article.data.pubDate} class="dt-published" />
 		<span>•</span>
 		<p>
 			<Icon icon="clock" size="1rem" />
@@ -41,7 +41,7 @@ const { text: readingTime } = await getReadingTime(article.body);
 		</p>
 	</div>
 
-	<h1>{article.data.title}</h1>
+	<h1 class="p-name">{article.data.title}</h1>
 
 	{article.data.categories?.length > 0 && <TagList tags={article.data.categories} />}
 </header>
@@ -73,7 +73,7 @@ const { text: readingTime } = await getReadingTime(article.body);
 		border-radius: inherit;
 	}
 
-	.author {
+	.p-author {
 		grid-column: 1;
 		grid-row: 1;
 		display: flex;
@@ -96,23 +96,23 @@ const { text: readingTime } = await getReadingTime(article.body);
 		margin-block-end: var(--theme-space-sm);
 		}
 
-		.author {
+		.p-author {
 			justify-self: end;
 			margin-inline-end: var(--theme-space-xl);
 		}
 	}
 
-	.author img {
+	.p-author img {
 		width: var(--theme-space-lg);
 		height: var(--theme-space-lg);
 	}
 
-	.author .u-name {
+	.p-author .p-name {
 		font-family: var(--font-brand);
 		font-weight: bold;
 	}
 
-	.author .u-nickname {
+	.p-author .p-nickname {
 		color: var(--theme-gray-300);
 		font-size: var(--theme-text-sm);
 		font-weight: 600;
diff --git a/examples/social-feed/src/components/Card.astro b/examples/social-feed/src/components/Card.astro
index 25e04f095..ab899c3fc 100644
--- a/examples/social-feed/src/components/Card.astro
+++ b/examples/social-feed/src/components/Card.astro
@@ -18,28 +18,28 @@ const cover = 'cover' in post.data && post.data.cover;
 const title = 'title' in post.data && post.data.title;
 ---
 
-<article {...attrs}>
-	<header>
-		<Image {...settings.avatar} width={120} class="u-image" />
-		<strong class="u-name">{settings.name}</strong>
-		<div class="u-nickname">
+<article class="h-entry" {...attrs}>
+	<header class="p-author h-card">
+		<Image {...settings.avatar} width={120} class="u-photo" />
+		<strong class="p-name">{settings.name}</strong>
+		<div class="p-nickname">
 			{settings.username}
 			 •
-			<FormattedDate date={pubDate} />
+			<FormattedDate date={pubDate} class="dt-published" />
 		</div>
 		{categories.length > 0 && <TagList tags={categories} class="tags" />}
 	</header>
-	{cover && <Image {...cover} width={1060} />}
-	{title && <h3>{title}</h3>}
+	{cover && <Image {...cover} width={1060} class="u-photo" />}
+	{title && <h3 class="p-name">{title}</h3>}
 	{
 		isArticle(post) ? (
-			<p>{post.data.description}</p>
+			<p class="p-summary">{post.data.description}</p>
 		) : (
-			post.render().then(({ Content }) => <Content />)
+			post.render().then(({ Content }) => <div class="e-content"><Content /></div>)
 		)
 	}
 	<footer>
-		<a href={`/post/${post.slug}/`}>Full {post.data.type === 'article' ? 'article' : 'note'}</a>
+		<a href={`/post/${post.slug}/`} class="u-url">Full {post.collection === 'articles' ? 'article' : 'note'}</a>
 		<a href={`javascript: navigator.clipboard.writeText(window.location.href + "post/${post.slug}/");`}>
 			<Icon icon="share" size="1.5rem" />
 			<span class="sr-only">Share this post</span>
@@ -65,19 +65,19 @@ const title = 'title' in post.data && post.data.title;
 		row-gap: var(--theme-space-2xs);
 		column-gap: var(--theme-space-sm);
 	}
-	.u-image {
+	.u-photo {
 		grid-area: avatar;
 		width: var(--theme-space-xl);
 		height: var(--theme-space-xl);
 		border-radius: var(--theme-radius-full);
 		background-color: var(--theme-shade-subtle);
 	}
-	.u-name {
+	.p-name {
 		grid-area: name;
 		font-family: var(--font-brand);
 		font-weight: bold;
 	}
-	.u-nickname {
+	.p-nickname {
 		grid-area: nickname;
 		font-size: var(--theme-text-sm);
 		color: var(--theme-gray-300);
diff --git a/examples/social-feed/src/components/FormattedDate.astro b/examples/social-feed/src/components/FormattedDate.astro
index 1bcce73a2..eac245a13 100644
--- a/examples/social-feed/src/components/FormattedDate.astro
+++ b/examples/social-feed/src/components/FormattedDate.astro
@@ -1,5 +1,7 @@
 ---
-interface Props {
+import type { HTMLAttributes } from 'astro/types';
+
+interface Props extends HTMLAttributes<'time'> {
 	date: Date;
 }
 
diff --git a/examples/social-feed/src/components/TagList.astro b/examples/social-feed/src/components/TagList.astro
index 14b68f82f..bd718f61f 100644
--- a/examples/social-feed/src/components/TagList.astro
+++ b/examples/social-feed/src/components/TagList.astro
@@ -9,7 +9,11 @@ const { tags, ...attrs } = Astro.props;
 ---
 
 <ul {...attrs}>
-	{tags.map((tag) => <li>{tag}</li>)}
+	{tags.map((tag) => (
+		<li>
+			<a href={`/category/${tag}/`} rel="category tag" class="p-category">{tag}</a>
+		</li>
+	))}
 </ul>
 
 <style>
diff --git a/examples/social-feed/src/components/UserProfile.astro b/examples/social-feed/src/components/UserProfile.astro
index ef264a159..91f0ad23a 100644
--- a/examples/social-feed/src/components/UserProfile.astro
+++ b/examples/social-feed/src/components/UserProfile.astro
@@ -6,14 +6,14 @@ import Icon from './Icon.astro';
 const socialLinks = Object.entries(settings.social);
 ---
 
-<div class="profile">
+<div class="h-card">
 	<div>
-		<div class="avatar">
+		<div class="u-photo">
 			<Image {...settings.avatar} width={220} />
 		</div>
 		<h1>
-			{settings.name}
-			<small>{settings.username}</small>
+			<span class="p-name">{settings.name}</span>
+			<small class="p-nickname">{settings.username}</small>
 		</h1>
 	</div>
 	<div class="bio-sections">
@@ -37,7 +37,7 @@ const socialLinks = Object.entries(settings.social);
 					<p>
 						<Icon icon="location-point" color="var(--theme-accent-dark)" size="1.75rem" />
 						<span class="sr-only">Location</span>
-						{settings.location}
+						<span class="p-locality">{settings.location}</span>
 					</p>
 				)
 			}
@@ -46,7 +46,7 @@ const socialLinks = Object.entries(settings.social);
 					<p>
 						<Icon icon="link-h" color="var(--theme-accent-dark)" size="1.75rem" />
 						<span class="sr-only">Homepage</span>
-						<a href={settings.homepage}>{settings.homepage.replace(/^https?:\/\/(www\.)?/, '')}</a>
+						<a href={settings.homepage} class="u-url">{settings.homepage.replace(/^https?:\/\/(www\.)?/, '')}</a>
 					</p>
 				)
 			}
@@ -57,9 +57,10 @@ const socialLinks = Object.entries(settings.social);
 		</div>
 		<ul class="social">
 			{
-				socialLinks.map(([key, { url }]) => (
+				socialLinks.map(([key, { url, title }]) => (
 					<li>
-						<a href={url}>
+						<a href={url} rel="me">
+							<span class="sr-only">{title}</span>
 							<Icon icon={`${key}`} size="1.75rem" />
 						</a>
 					</li>
@@ -70,18 +71,18 @@ const socialLinks = Object.entries(settings.social);
 </div>
 
 <style>
-	.profile {
+	.h-card {
 		display: flex;
 		flex-direction: column;
 		gap: var(--theme-space-md);
 	}
 
-	.avatar {
+	.u-photo {
 		display: inline-block;
 		position: relative;
 	}
 
-	.avatar::after {
+	.u-photo::after {
 		border-radius: var(--theme-radius-full);
 		position: absolute;
 		content: '';
@@ -89,7 +90,7 @@ const socialLinks = Object.entries(settings.social);
 		border: 3px solid var(--theme-text);
 	}
 
-	.avatar img {
+	.u-photo img {
 		width: 110px;
 		height: 110px;
 	}
diff --git a/examples/social-feed/src/content/config.ts b/examples/social-feed/src/content/config.ts
index f17d3814a..1ba864dd4 100644
--- a/examples/social-feed/src/content/config.ts
+++ b/examples/social-feed/src/content/config.ts
@@ -16,6 +16,7 @@ const articles = defineCollection({
 		})
 		.required({
 			// requiring the description for articles, this will be shown as the short preview text on cards
+			title: true,
 			description: true
 		})
 		.strict(),
diff --git a/examples/social-feed/src/helpers/getSortedPosts.ts b/examples/social-feed/src/helpers/getSortedPosts.ts
index beb364195..3b6389266 100644
--- a/examples/social-feed/src/helpers/getSortedPosts.ts
+++ b/examples/social-feed/src/helpers/getSortedPosts.ts
@@ -1,4 +1,13 @@
 import { getCollection } from 'astro:content';
+import type { Article, Note } from '../content/config';
+
+export function sortPosts(order: 'asc' | 'desc' = 'desc') {
+	return function(a: Article | Note, b: Article | Note) {
+		return order === 'asc'
+			? a.data.pubDate.getTime() - b.data.pubDate.getTime()
+			: b.data.pubDate.getTime() - a.data.pubDate.getTime()
+	}
+}
 
 /** Get everything in your posts collection, sorted by date. */
 export async function getSortedPosts(order: 'asc' | 'desc' = 'desc') {
@@ -6,8 +15,10 @@ export async function getSortedPosts(order: 'asc' | 'desc' = 'desc') {
 		getCollection('articles'),
 		getCollection('notes'),
 	])
-		.then((collections) => collections.flat())
-	posts.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime());
-	if (order === 'asc') posts.reverse();
+		.then((collections) => collections
+			.flat()
+			.sort(sortPosts(order)
+		));
+
 	return posts;
 }
diff --git a/examples/social-feed/src/pages/rss.xml.ts b/examples/social-feed/src/pages/rss.xml.ts
index 1687e0561..520e5d1dc 100644
--- a/examples/social-feed/src/pages/rss.xml.ts
+++ b/examples/social-feed/src/pages/rss.xml.ts
@@ -1,12 +1,14 @@
 import rss from '@astrojs/rss';
 import type { APIContext } from 'astro';
-import { getSortedPosts } from '../helpers/getSortedPosts';
+import { sortPosts } from '../helpers/getSortedPosts';
 import settings from '../settings';
+import { getCollection } from 'astro:content';
 
 const { title, description } = settings.rss;
 
-export async function get(context: APIContext) {
-	const posts = await getSortedPosts();
+export async function GET(context: APIContext) {
+	const posts = await getCollection('articles');
+
 	return rss({
 		// `<title>` field in output xml
 		title,
@@ -17,7 +19,9 @@ export async function get(context: APIContext) {
 		site: context.site!.href,
 		// Array of `<item>`s in output xml
 		// See "Generating items" section for examples using content collections and glob imports
-		items: posts.map(({ data, slug }) => ({ ...data, link: `/post/${slug}` })),
+		items: posts
+			.sort(sortPosts())
+			.map(({ data, slug }) => ({ ...data, link: `/post/${slug}` })),
 		stylesheet: '/rss/styles.xsl',
 	});
 }