aboutsummaryrefslogtreecommitdiff
path: root/website/src/pages/blog
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-09-01 14:48:45 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-09-01 14:48:45 +0300
commit8a6d697308162874a236c84aac0b0f8c7ac01f83 (patch)
treeed7dc7e8c6f50d66bde721fae78576aede929f66 /website/src/pages/blog
parentb54a78aa510b87d1e3b56c619b72eaeb59e4a2a1 (diff)
refactor: separate website presentation from runtime
Diffstat (limited to 'website/src/pages/blog')
-rw-r--r--website/src/pages/blog/[slug].astro95
-rw-r--r--website/src/pages/blog/index.astro42
2 files changed, 0 insertions, 137 deletions
diff --git a/website/src/pages/blog/[slug].astro b/website/src/pages/blog/[slug].astro
deleted file mode 100644
index 3c33a38c..00000000
--- a/website/src/pages/blog/[slug].astro
+++ /dev/null
@@ -1,95 +0,0 @@
----
-import { getCollection, render } from 'astro:content';
-import SiteLayout from '../../components/SiteLayout.astro';
-import AuthorCard from '../../components/AuthorCard.astro';
-
-export async function getStaticPaths() {
- const posts = await getCollection('blog');
- /* dev only, see blog/index.astro */
- return posts
- .filter((post) => import.meta.env.DEV || !post.data.draft)
- .map((post) => {
- const slug = post.id.replace(/\.(md|mdx)$/i, '');
- return { params: { slug }, props: { post, slug } };
- });
-}
-
-const { post, slug } = Astro.props;
-const { Content, headings } = await render(post);
-const sectionHeadings = headings.filter((heading) => heading.depth === 2);
----
-
-<SiteLayout
- title={`${post.data.title} — Herdr blog`}
- description={post.data.description}
- canonicalPath={`/blog/${slug}/`}
- ogType="article"
- ogImage={post.data.ogImage}
- ogImageAlt={post.data.ogImage ? post.data.title : undefined}
->
- {/* a post with no h2s renders no sidebar, so the grid must stop reserving
- a column for it */}
- <div class:list={['article', sectionHeadings.length === 0 && 'article-solo']}>
- <article class="article-body">
- <p class="article-meta">
- <a href="/blog/">← Blog</a>
- <time datetime={post.data.date.toISOString()}>
- {post.data.date.toLocaleDateString('en', {
- year: 'numeric',
- month: 'long',
- day: 'numeric',
- })}
- </time>
- </p>
- <h1>{post.data.title}</h1>
- {post.data.lede && post.data.description && (
- <p class="article-lede">{post.data.description}</p>
- )}
- <hr class="article-rule" />
- <div class="prose">
- <Content />
- </div>
- <AuthorCard />
- </article>
-
- {sectionHeadings.length > 0 && (
- <aside class="toc" aria-label="Article sections">
- <p>Sections</p>
- <nav>
- {sectionHeadings.map((heading) => (
- <a href={`#${heading.slug}`} data-heading-link={heading.slug}>{heading.text}</a>
- ))}
- </nav>
- </aside>
- )}
- </div>
-
- <script>
- const headings = Array.from(document.querySelectorAll('.prose h2[id]'));
- const links = new Map(
- Array.from(document.querySelectorAll('[data-heading-link]')).map((link) => [
- link.getAttribute('data-heading-link'),
- link,
- ]),
- );
-
- function setActive(id) {
- for (const link of links.values()) link.removeAttribute('aria-current');
- links.get(id)?.setAttribute('aria-current', 'true');
- }
-
- if (headings.length > 0 && links.size > 0) {
- setActive(headings[0].id);
- const observer = new IntersectionObserver(
- (entries) => {
- const visible = entries
- .filter((entry) => entry.isIntersecting)
- .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top)[0];
- if (visible?.target instanceof HTMLElement) setActive(visible.target.id);
- },
- { rootMargin: '-18% 0px -68% 0px', threshold: 0 },
- );
- for (const heading of headings) observer.observe(heading);
- }
- </script>
-</SiteLayout>
diff --git a/website/src/pages/blog/index.astro b/website/src/pages/blog/index.astro
deleted file mode 100644
index de9349ea..00000000
--- a/website/src/pages/blog/index.astro
+++ /dev/null
@@ -1,42 +0,0 @@
----
-import { getCollection } from 'astro:content';
-import SiteLayout from '../../components/SiteLayout.astro';
-
-/* Drafts render locally and never in a build, so an unpublished post can be
- reviewed on the dev server without being one deploy away from going live. */
-const posts = (await getCollection('blog'))
- .filter((post) => import.meta.env.DEV || !post.data.draft)
- .map((post) => ({ ...post, slug: post.id.replace(/\.(md|mdx)$/i, '') }))
- .sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
-
-const stamp = (date) =>
- date.toLocaleDateString('en', { year: 'numeric', month: 'short', day: 'numeric' });
----
-
-<SiteLayout
- title="Herdr blog"
- description="Notes on the agent runtime — product decisions, implementation writeups, and what we learned running agents on machines nobody is watching."
- canonicalPath="/blog/"
->
- <header class="ph">
- <div class="hd-eyebrow"><s></s>the blog</div>
- <h1>Notes from the herd.</h1>
- <p>
- Product decisions, implementation writeups, and what we learn running agents on
- machines nobody is watching.
- </p>
- </header>
-
- <div class="posts">
- {posts.map((post) => (
- <a href={`/blog/${post.slug}/`}>
- <time datetime={post.data.date.toISOString()}>{stamp(post.data.date)}</time>
- <div>
- <h2>{post.data.title}</h2>
- {post.data.description && <p>{post.data.description}</p>}
- </div>
- <span class="go-arrow" aria-hidden="true">→</span>
- </a>
- ))}
- </div>
-</SiteLayout>