summaryrefslogtreecommitdiff
path: root/examples/blog/src
diff options
context:
space:
mode:
authorGravatar Fred K. Schott <fkschott@gmail.com> 2021-06-28 15:29:16 -0700
committerGravatar GitHub <noreply@github.com> 2021-06-28 15:29:16 -0700
commit5591d4eb9fc70e781804f940fabd334b53ce7056 (patch)
tree9c4c4ebaf708e959a96b1fc9cede9c1fc9cc40b5 /examples/blog/src
parent7063c04dec48fcabcda104c42d61642a554f6044 (diff)
downloadastro-5591d4eb9fc70e781804f940fabd334b53ce7056.tar.gz
astro-5591d4eb9fc70e781804f940fabd334b53ce7056.tar.zst
astro-5591d4eb9fc70e781804f940fabd334b53ce7056.zip
update the blog example (#565)
Diffstat (limited to 'examples/blog/src')
-rw-r--r--examples/blog/src/components/Author.astro16
-rw-r--r--examples/blog/src/components/BaseHead.astro36
-rw-r--r--examples/blog/src/components/BlogHeader.astro90
-rw-r--r--examples/blog/src/components/BlogPost.astro86
-rw-r--r--examples/blog/src/components/BlogPostPreview.astro57
-rw-r--r--examples/blog/src/components/Logo.astro56
-rw-r--r--examples/blog/src/components/MainHead.astro42
-rw-r--r--examples/blog/src/components/Nav.astro63
-rw-r--r--examples/blog/src/components/Pagination.astro44
-rw-r--r--examples/blog/src/components/PostPreview.astro66
-rw-r--r--examples/blog/src/data/authors.json10
-rw-r--r--examples/blog/src/layouts/BlogPost.astro23
-rw-r--r--examples/blog/src/layouts/post.astro78
-rw-r--r--examples/blog/src/pages/$author.astro110
-rw-r--r--examples/blog/src/pages/$posts.astro83
-rw-r--r--examples/blog/src/pages/about.astro63
-rw-r--r--examples/blog/src/pages/index.astro100
-rw-r--r--examples/blog/src/pages/post/chapter-i.md13
-rw-r--r--examples/blog/src/pages/post/chapter-ii.md15
-rw-r--r--examples/blog/src/pages/post/chapter-iii.md13
-rw-r--r--examples/blog/src/pages/posts/introducing-astro.md90
21 files changed, 521 insertions, 633 deletions
diff --git a/examples/blog/src/components/Author.astro b/examples/blog/src/components/Author.astro
new file mode 100644
index 000000000..87cb48c45
--- /dev/null
+++ b/examples/blog/src/components/Author.astro
@@ -0,0 +1,16 @@
+---
+export interface Props {
+ name: string;
+ href: string;
+}
+
+const { name, href } = Astro.props;
+---
+<style>
+ .author {
+ margin-bottom: 0.75rem;
+ }
+</style>
+<div class="author">
+ <p><a href={href}>{name}</a></p>
+</div>
diff --git a/examples/blog/src/components/BaseHead.astro b/examples/blog/src/components/BaseHead.astro
new file mode 100644
index 000000000..4905e1b7a
--- /dev/null
+++ b/examples/blog/src/components/BaseHead.astro
@@ -0,0 +1,36 @@
+---
+export interface Props {
+ title: string;
+ description: string;
+ permalink: string;
+}
+const { title, description, permalink } = Astro.props;
+---
+
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
+
+<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+
+<!-- Primary Meta Tags -->
+<title>{title}</title>
+<meta name="title" content={title} />
+<meta name="description" content={description} />
+
+<!-- Open Graph / Facebook -->
+<meta property="og:type" content="website" />
+<meta property="og:url" content={permalink} />
+<meta property="og:title" content={title} />
+<meta property="og:description" content={description} />
+<meta property="og:image" content="https://astro.build/social.jpg?v=1" />
+
+<!-- Twitter -->
+<meta property="twitter:card" content="summary_large_image" />
+<meta property="twitter:url" content={permalink} />
+<meta property="twitter:title" content={title} />
+<meta property="twitter:description" content={description} />
+<meta property="twitter:image" content="https://astro.build/social.jpg?v=1" />
+
+<!-- Fonts -->
+<link rel="preconnect" href="https://fonts.gstatic.com" />
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&family=IBM+Plex+Sans:wght@400;700&display=swap">
diff --git a/examples/blog/src/components/BlogHeader.astro b/examples/blog/src/components/BlogHeader.astro
new file mode 100644
index 000000000..347ce3a05
--- /dev/null
+++ b/examples/blog/src/components/BlogHeader.astro
@@ -0,0 +1,90 @@
+<header class="layout">
+ <article>
+ <h1>
+ <a href="/">
+ <svg class="logo" width="32" height="32" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <style>
+ #flame {
+ fill: #ff5d01;
+ }
+ #a {
+ fill: #000014;
+ }
+ </style>
+ <title>Logo</title>
+ <path
+ id="a"
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z"
+ />
+ <path
+ id="flame"
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z"
+ />
+ </svg>
+ <span>My Blog</span>
+ </a>
+ </h1>
+ </article>
+</header>
+
+<style>
+header {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+ height: 5rem;
+}
+article {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+.header-subitem {
+ display: flex;
+ flex-grow: 0;
+ gap: 0.5em;
+ align-items: center;
+ justify-content: center;
+ color: var(--theme-text-lighter);
+ font-size: initial;
+ padding: 0.5rem;
+}
+.header-subitem:hover {
+ color: var(--theme-accent);
+}
+.header-subitem svg {
+ width: 1.5rem;
+ height: 1.5rem;
+}
+
+@media (max-width: 32em) {
+ .header-subitem {
+ display: none;
+ }
+}
+
+h1 {
+ margin: 0;
+ font-size: 1.5rem;
+ max-width: 100%;
+ display: flex;
+ flex-grow: 1;
+}
+
+.logo {
+ transform: translateY(0.25rem);
+}
+
+svg {
+ width: 2.5rem;
+ height: 2.5rem;
+}
+
+h1 a {
+ text-decoration: none;
+ display: inline-flex;
+}
+</style>
diff --git a/examples/blog/src/components/BlogPost.astro b/examples/blog/src/components/BlogPost.astro
new file mode 100644
index 000000000..95116b2e7
--- /dev/null
+++ b/examples/blog/src/components/BlogPost.astro
@@ -0,0 +1,86 @@
+---
+import Author from './Author.astro';
+
+export interface Props {
+ title: string;
+ author: string;
+ publishDate: string;
+ heroImage: string;
+}
+
+const { title, author, publishDate, heroImage } = Astro.props;
+---
+
+<div class="layout">
+ <article class="content">
+ <div>
+ <header>
+ {heroImage && <img width="720" height="420" class="hero-image" loading="lazy" src={heroImage} />}
+ <p class="publish-date">{publishDate}</p>
+ <h1 class="title">{title}</h1>
+ <Author name="@FredKSchott" url="https://twitter.com/FredKSchott" />
+ </header>
+ <main>
+ <slot />
+ </main>
+ </article>
+</div>
+
+<style>
+.hero-image {
+ width: 100vw;
+ object-fit: cover;
+ object-position: center;
+ margin-top: 2rem;
+ margin-bottom: 4rem;
+ max-width: 1280px;
+}
+
+@media (max-width: 50em) {
+ .hero-image {
+ height: 260px;
+ margin-top: 0;
+ margin-bottom: 2rem;
+ }
+}
+
+.content {
+ margin-bottom: 8rem;
+}
+
+.content :global(main > * + *) {
+ margin-top: 1rem;
+}
+
+.content :global(h2) {
+ margin-top: 4rem;
+}
+
+header {
+ display: flex;
+ flex-direction: column;
+ text-align: center;
+ align-items: center;
+ justify-content: center;
+
+ padding-bottom: 2rem;
+ margin-bottom: 2rem;
+ border-bottom: 4px solid var(--theme-divider);
+}
+
+.title,
+.author,
+.publish-date {
+ margin: 0;
+}
+
+.publish-date,
+.author {
+ color: var(--theme-text-lighter);
+}
+
+.title {
+ font-size: 2.25rem;
+ font-weight: 700;
+}
+</style>
diff --git a/examples/blog/src/components/BlogPostPreview.astro b/examples/blog/src/components/BlogPostPreview.astro
new file mode 100644
index 000000000..9e698fb6e
--- /dev/null
+++ b/examples/blog/src/components/BlogPostPreview.astro
@@ -0,0 +1,57 @@
+---
+export interface Props {
+ post: any;
+}
+
+const { post } = Astro.props;
+---
+<article class="post-preview">
+ <header>
+ <h3 class="publish-date">{post.publishDate}</h3>
+ <a href={post.url}><h1 class="title">{post.title}</h1></a>
+ </header>
+ <main>
+ <p>{post.description}</p>
+ <a href={post.url}>Read more</a>
+ </main>
+</article>
+
+<style>
+.content :global(main > * + *) {
+ margin-top: 1rem;
+}
+
+.post-preview {
+ padding-bottom: 2rem;
+ margin-bottom: 2rem;
+ border-bottom: 4px solid var(--theme-divider);
+}
+
+header {
+ display: flex;
+ flex-direction: column;
+ text-align: left;
+ align-items: flex-start;
+ justify-content: center;
+
+ padding-bottom: 2rem;
+}
+
+.title,
+.author,
+.publish-date {
+ margin: 0;
+}
+
+.publish-date,
+.author {
+ font-size: 1.25rem;
+ color: var(--theme-text-lighter);
+}
+
+.title {
+ font-size: 2.25rem;
+ font-weight: 700;
+ color: var(--theme-text);
+}
+</style>
diff --git a/examples/blog/src/components/Logo.astro b/examples/blog/src/components/Logo.astro
new file mode 100644
index 000000000..7926dab4d
--- /dev/null
+++ b/examples/blog/src/components/Logo.astro
@@ -0,0 +1,56 @@
+<svg class="logo" width="158" height="170" viewBox="0 0 158 170" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M96.5039 9.46441C97.4758 10.671 97.9714 12.2991 98.9626 15.5553L120.617 86.6902C112.611 82.5368 103.907 79.5413 94.7281 77.9252L80.6289 30.2798C80.3982 29.5002 79.6822 28.9654 78.8692 28.9654C78.0541 28.9654 77.3367 29.503 77.1079 30.2853L63.1795 77.9011C53.9579 79.51 45.2146 82.5109 37.1741 86.6793L58.9347 15.5388C59.929 12.2882 60.4262 10.6629 61.3981 9.45854C62.2562 8.39532 63.3723 7.56959 64.64 7.06003C66.076 6.48285 67.7756 6.48285 71.1749 6.48285H86.7174C90.1211 6.48285 91.823 6.48285 93.2603 7.06124C94.5291 7.575 95.6459 8.39925 96.5039 9.46441Z" fill="white" />
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M99.0951 90.0755C95.5253 93.1279 88.4002 95.2097 80.1929 95.2097C70.1197 95.2097 61.6767 92.0737 59.4363 87.8561C58.6354 90.2733 58.4558 93.0397 58.4558 94.8069C58.4558 94.8069 57.9281 103.485 63.9636 109.52C63.9636 106.386 66.5042 103.846 69.6381 103.846C75.0097 103.846 75.0036 108.532 74.9987 112.334C74.9986 112.448 74.9984 112.561 74.9984 112.673C74.9984 118.444 78.5255 123.391 83.5416 125.477C82.7924 123.936 82.3721 122.205 82.3721 120.377C82.3721 114.873 85.6034 112.823 89.3588 110.441C92.3469 108.546 95.6668 106.441 97.9548 102.217C99.1486 100.013 99.8265 97.4893 99.8265 94.8069C99.8265 93.1573 99.5702 91.5676 99.0951 90.0755Z" fill="#FF5D01" />
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M99.0951 90.0755C95.5253 93.1279 88.4002 95.2097 80.1929 95.2097C70.1197 95.2097 61.6767 92.0737 59.4363 87.8561C58.6354 90.2733 58.4558 93.0397 58.4558 94.8069C58.4558 94.8069 57.9281 103.485 63.9636 109.52C63.9636 106.386 66.5042 103.846 69.6381 103.846C75.0097 103.846 75.0036 108.532 74.9987 112.334C74.9986 112.448 74.9984 112.561 74.9984 112.673C74.9984 118.444 78.5255 123.391 83.5416 125.477C82.7924 123.936 82.3721 122.205 82.3721 120.377C82.3721 114.873 85.6034 112.823 89.3588 110.441C92.3469 108.546 95.6668 106.441 97.9548 102.217C99.1486 100.013 99.8265 97.4893 99.8265 94.8069C99.8265 93.1573 99.5702 91.5676 99.0951 90.0755Z" fill="url(#paint1_linear)" />
+ <path d="M11.9957 169.024C20.0117 169.024 24.8597 167.104 27.6917 163.12C27.6917 164.896 27.7877 166.576 28.0277 168.112H32.7797C32.3477 165.616 32.2517 163.984 32.2517 159.472V153.328C32.2517 146.704 27.1157 143.2 17.3237 143.2C7.8677 143.2 1.7237 146.848 0.955701 152.128H5.9957C6.7637 148.576 10.7477 146.704 17.3237 146.704C23.8037 146.704 27.6437 148.96 27.6437 152.8V153.28L12.6677 154.144C6.5717 154.48 4.3157 155.344 2.5877 156.592C0.955701 157.792 0.0437012 159.664 0.0437012 161.824C0.0437012 166.384 4.7477 169.024 11.9957 169.024ZM13.5317 165.616C7.9637 165.616 4.8917 164.32 4.8917 161.728C4.8917 158.944 6.8117 157.696 13.5797 157.264L27.6437 156.4V157.504C27.6437 162.544 21.7397 165.616 13.5317 165.616Z" fill="white" />
+ <path d="M55.9352 169.024C65.8712 169.024 69.8552 165.76 69.8552 161.008C69.8552 157.072 67.4072 155.056 61.1672 154.528L49.5032 153.616C46.3352 153.376 44.5592 152.464 44.5592 150.496C44.5592 148 47.2952 146.704 53.1992 146.704C59.9192 146.704 63.4232 148.048 65.7272 151.024L69.6152 149.152C67.2152 145.408 61.8872 143.2 53.6312 143.2C45.1352 143.2 40.0472 146.032 40.0472 150.688C40.0472 154.864 43.0712 156.88 48.7832 157.36L60.3512 158.272C64.1432 158.56 65.2952 159.328 65.2952 161.296C65.2952 164.128 62.3672 165.472 56.5592 165.472C49.5032 165.472 45.0392 163.552 42.8792 160.048L39.0872 162.112C42.0152 166.528 47.1512 169.024 55.9352 169.024Z" fill="white" />
+ <path d="M79.6765 147.712V159.28C79.6765 164.032 81.3085 168.784 90.1885 168.784C92.4445 168.784 95.1805 168.352 96.3805 167.824V163.936C94.7005 164.32 92.6845 164.608 90.7165 164.608C86.5405 164.608 84.2845 162.976 84.2845 158.848V147.712H96.2845V144.112H84.2845V136L79.6765 137.872V144.112H72.1404V147.712H79.6765Z" fill="white" />
+ <path d="M107.728 144.112H103.504V168.112H108.064V159.136C108.064 155.68 108.736 152.752 110.656 150.736C112.336 148.864 114.496 147.808 118.288 147.808C119.584 147.808 120.4 147.904 121.504 148.096V143.68C120.496 143.44 119.632 143.392 118.336 143.392C113.2 143.392 109.12 146.416 107.728 151.072V144.112Z" fill="white" />
+ <path d="M140.724 169.024C150.948 169.024 157.956 163.84 157.956 156.112C157.956 148.384 150.948 143.2 140.724 143.2C130.5 143.2 123.492 148.384 123.492 156.112C123.492 163.84 130.5 169.024 140.724 169.024ZM140.724 165.232C133.188 165.232 128.34 161.68 128.34 156.112C128.34 150.544 133.188 146.992 140.724 146.992C148.212 146.992 153.108 150.544 153.108 156.112C153.108 161.68 148.212 165.232 140.724 165.232Z" fill="white" />
+ <defs>
+ <linearGradient id="paint1_linear" x1="115.168" y1="65.245" x2="94.0326" y2="109.491" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#FF1639" />
+ <stop offset="1" stop-color="#FF1639" stop-opacity="0" />
+ </linearGradient>
+ </defs>
+</svg>
+
+<style lang="scss">
+ .logo {
+ margin: 2rem auto;
+ }
+
+ .title {
+ font-family: var(--font-sans);
+ font-size: 1rem;
+ }
+ .title svg {
+ margin-right: -100%;
+ }
+ .title svg text {
+ font-size: 16px;
+ font-family: var(--font-sans);
+ }
+ .title svg text.span {
+ fill: white;
+ font-size: 16.2px;
+ transform: translate(0, 18px);
+ }
+ .title svg text.em {
+ fill: var(--color-green);
+ transform: translate(0, 36px);
+ }
+
+ @media (min-width: 40em) {
+ .title svg {
+ margin-right: 0;
+ margin-bottom: -40px;
+ }
+ .title svg text.span {
+ font-size: 16px;
+ }
+ .title svg text.em {
+ transform: translate(190px, 18px);
+ }
+ }
+</style>
diff --git a/examples/blog/src/components/MainHead.astro b/examples/blog/src/components/MainHead.astro
deleted file mode 100644
index fbdaa2965..000000000
--- a/examples/blog/src/components/MainHead.astro
+++ /dev/null
@@ -1,42 +0,0 @@
----
-export interface Props {
- title: string;
- description: string;
- image?: string;
- type?: string;
- next?: string;
- prev?: string;
- canonicalURL?: string;
-}
-
-const { title, description, image, type, next, prev, canonicalURL } = Astro.props as Props;
----
-
-<!-- Common -->
-<meta charset="UTF-8">
-<title>{title}</title>
-<meta name="description" content={description}>
-<link rel="preconnect" href="https://fonts.gstatic.com">
-<link href="https://fonts.googleapis.com/css2?family=Spectral:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
-<link rel="stylesheet" href="/global.css">
-<!-- Sitemap -->
-<link rel="sitemap" href="/sitemap.xml">
-<!-- RSS -->
-<link rel="alternate" type="application/rss+xml" href="/feed/posts.xml">
-
-<!-- SEO -->
-<link rel="canonical" href={canonicalURL}>
-{next && <link rel="next" aria-label="Previous Page" href={new URL(next, canonicalURL).href}>}
-{prev && <link rel="prev" aria-label="Next Page" href={new URL(prev, canonicalURL).href}>}
-
-<!-- OpenGraph -->
-<meta property="og:title" content={title}>
-<meta property="og:description" content={description}>
-{image && (<meta property="og:image" content={new URL(image, canonicalURL)}>)}
-
-<!-- Twitter -->
-<meta name="twitter:card" content={image ? 'summary_large_image' : 'summary'}>
-<meta name="twitter:site" content="@astro">
-<meta name="twitter:title" content={title}>
-<meta name="twitter:description" content={description}>
-{image && (<meta name="twitter:image" content={image}>)}
diff --git a/examples/blog/src/components/Nav.astro b/examples/blog/src/components/Nav.astro
deleted file mode 100644
index a7ef0985f..000000000
--- a/examples/blog/src/components/Nav.astro
+++ /dev/null
@@ -1,63 +0,0 @@
----
-export interface Props {
- title: string;
-}
-const { title } = Astro.props;
----
-
-<style lang="scss">
-.header {
- text-align: center;
-
- @media (min-width: 600px) {
- display: flex;
- align-items: center;
- padding: 2rem;
- }
-}
-
-.title {
- margin: 0;
- font-size: 1.2em;
- letter-spacing: -0.03em;
- font-weight: 400;
- margin-right: 1em;
-}
-
-.nav {
- text-align: center;
-
- @media (min-width: 600px) {
- display: flex;
- }
-}
-
-ul {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-li {
- margin: 0;
-}
-
-a {
- display: block;
- font-size: 1.2em;
- letter-spacing: -0.02em;
- margin-left: 0.75em;
- margin-right: 0.75em;
-}
-</style>
-
-<nav class="header">
- <h1 class="title">Don’s Blog</h1>
- <ul class="nav">
- <li><a href="/">Home</a></li>
- <li><a href="/posts">All Posts</a></li>
- <li><a href="/author/don">Author: Don</a></li>
- <li><a href="/author/sancho">Author: Sancho</a></li>
- <li><a href="/about">About</a></li>
- </ul>
-</nav>
diff --git a/examples/blog/src/components/Pagination.astro b/examples/blog/src/components/Pagination.astro
deleted file mode 100644
index 401931c07..000000000
--- a/examples/blog/src/components/Pagination.astro
+++ /dev/null
@@ -1,44 +0,0 @@
----
-export interface Props {
- prevUrl: string;
- nextUrl: string;
-}
-
-const { prevUrl, nextUrl } = Astro.props;
----
-
-<style lang="scss">
-.nav {
- display: flex;
- margin-right: auto;
- margin-left: auto;
- padding-top: 4rem;
- padding-bottom: 4rem;
-}
-
-.prev,
-.next {
- display: block;
- text-transform: uppercase;
- font-size: 0.8em;
-
- &[href="#"] {
- display: none;
- }
-}
-
-.prev {
- margin-right: auto;
-}
-
-.next {
- margin-left: auto;
-}
-</style>
-
-<div class="wrapper">
- <nav class="nav">
- <a class="prev" href={prevUrl || '#'} aria-label="Previous Page">Prev</a>
- <a class="next" href={nextUrl || '#'} aria-label="Next Page">Next</a>
- </nav>
-</div>
diff --git a/examples/blog/src/components/PostPreview.astro b/examples/blog/src/components/PostPreview.astro
deleted file mode 100644
index b126ca2fb..000000000
--- a/examples/blog/src/components/PostPreview.astro
+++ /dev/null
@@ -1,66 +0,0 @@
----
-export interface Props {
- post: any;
- author: string;
-}
-const { post, author } = Astro.props;
-
-function formatDate(date) {
- return new Date(date).toUTCString().replace(/(\d\d\d\d) .*/, '$1'); // remove everything after YYYY
-}
----
-
-<style lang="scss">
-.post {
- padding-top: 6rem;
- padding-bottom: 6rem;
- border-bottom: 1px solid rgba(black, 0.25);
- text-align: center;
-}
-
-.author {
- text-transform: uppercase;
-}
-
-.date {
- font-style: italic;
-}
-
-.description {
- font-size: 1.25em;
-}
-
-.link {
- text-transform: uppercase;
- font-size: 0.8em;
- margin-left: 1em;
-}
-
-h2 {
- font-weight: 700;
- font-size: 2.75em;
- line-height: 1;
- letter-spacing: -0.04em;
- margin-top: 0;
- margin-bottom: 0;
-}
-
-time {
- display: block;
- margin-top: 0.25rem;
- margin-bottom: 0.5em;
-}
-</style>
-
-<article class="post">
-
- <div class="data">
- <h2>{post.title}</h2>
- <a class="author" href={`/author/${post.author}`}>{author.name}</a>
- <time class="date" datetime={post.date}>{formatDate(post.date)}</time>
- <p class="description">
- {post.description}
- <a class="link" href={post.url} aria-label={`Read ${post.title}`}>Read</a>
- </p>
- </div>
-</article>
diff --git a/examples/blog/src/data/authors.json b/examples/blog/src/data/authors.json
deleted file mode 100644
index e958e7cd1..000000000
--- a/examples/blog/src/data/authors.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "don": {
- "name": "Don Quixote",
- "image": "/authors/don.jpg"
- },
- "sancho": {
- "name": "Sancho Panza",
- "image": "/authors/sancho.jpg"
- }
-}
diff --git a/examples/blog/src/layouts/BlogPost.astro b/examples/blog/src/layouts/BlogPost.astro
new file mode 100644
index 000000000..e6b644789
--- /dev/null
+++ b/examples/blog/src/layouts/BlogPost.astro
@@ -0,0 +1,23 @@
+---
+import { Markdown } from 'astro/components';
+import BaseHead from '../components/BaseHead.astro';
+import BlogHeader from '../components/BlogHeader.astro';
+import BlogPost from '../components/BlogPost.astro';
+
+const {content} = Astro.props;
+const {title, description, publishDate, author, heroImage, permalink} = content;
+---
+<html>
+ <head>
+ <BaseHead title={title} description={description} permalink={permalink} />
+ <link rel="stylesheet" href="/blog.css" />
+ </head>
+
+ <body>
+ <BlogHeader />
+ <BlogPost title={title} author={author} heroImage={heroImage} publishDate={publishDate}>
+ <slot />
+ </BlogPost>
+ </body>
+</html>
+
diff --git a/examples/blog/src/layouts/post.astro b/examples/blog/src/layouts/post.astro
deleted file mode 100644
index c8f394892..000000000
--- a/examples/blog/src/layouts/post.astro
+++ /dev/null
@@ -1,78 +0,0 @@
----
-import MainHead from '../components/MainHead.astro';
-import Nav from '../components/Nav.astro';
-import authorData from '../data/authors.json';
-
-const { content } = Astro.props;
----
-
-<html>
- <head>
- <title>{content.title}</title>
- <MainHead title={content.title} description={content.description} image={content.image} canonicalURL={Astro.request.canonicalURL} />
- <style lang="scss">
- .title {
- margin-top: 4rem;
- margin-bottom: 4rem;
- font-size: 3em;
- letter-spacing: -0.04em;
- text-align: center;
- }
-
- .description {
- margin-bottom: 4rem;
- font-size: 1.4em;
- font-weight: 400;
- text-align: justify;
- text-transform: uppercase;
- }
-
- .img {
- display: block;
- width: 100%;
- height: auto;
- }
-
- .article {
- margin-top: 4rem;
- margin-bottom: 6rem;
-
- :global(p) {
- font-size: 1.3em;
- line-height: 2;
- margin-top: 2em;
- margin-bottom: 2em;
- }
- }
-
- .posts {
- text-transform: uppercase;
- }
-
- .footer {
- margin-top: 6rem;
- padding-bottom: 6rem;
- text-align: center;
- }
- </style>
- </head>
-
- <body>
- <Nav />
-
- <main class="wrapper">
- <h2 class="title">{content.title}</h2>
- <p class="description">{content.description}</p>
- <img class="img" src={content.image} alt="">
- <article class="article">
- <slot />
- </article>
- <footer class="footer">
- <a class="posts" href="/posts">All Posts</a>
- </footer>
- </main>
-
- <footer>
- </footer>
- </body>
-</html>
diff --git a/examples/blog/src/pages/$author.astro b/examples/blog/src/pages/$author.astro
deleted file mode 100644
index ff80344e4..000000000
--- a/examples/blog/src/pages/$author.astro
+++ /dev/null
@@ -1,110 +0,0 @@
----
-import MainHead from '../components/MainHead.astro';
-import Nav from '../components/Nav.astro';
-import PostPreview from '../components/PostPreview.astro';
-import Pagination from '../components/Pagination.astro';
-
-// page
-let title = 'Don’s Blog';
-let description = 'An example blog on Astro';
-let canonicalURL = Astro.request.canonicalURL;
-
-// collection
-import authorData from '../data/authors.json';
-
-let { collection } = Astro.props;
-export async function createCollection() {
- /** Load posts */
- let allPosts = Astro.fetchContent('./post/*.md');
- let allAuthors = new Set();
-
- /** Loop through all posts, gather all authors */
- let routes = [];
- for (const post of allPosts) {
- if (!allAuthors.has(post.author)) {
- allAuthors.add(post.author);
- routes.push({ author: post.author });
- }
- }
-
- return {
- /** Sort posts newest -> oldest, filter by params.author */
- async data({ params }) {
- allPosts.sort((a, b) => new Date(b.date) - new Date(a.date));
- return allPosts.filter((post) => post.author === params.author);
- },
- /** Set page size */
- pageSize: 3,
- /** Set permalink URL */
- permalink: ({ params }) => `/author/${params.author}`,
- /** Pass back all routes so Astro can generate the static build */
- routes,
- };
-}
-
-const author = authorData[collection.params.author];
----
-
-<html>
- <head>
- <title>{title}</title>
- <MainHead
- title={title}
- description={description}
- image={collection.data[0].image}
- canonicalURL={canonicalURL}
- prev={collection.url.prev}
- next={collection.url.next}
- />
-
- <style lang="scss">
- .title {
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 3em;
- letter-spacing: -0.04em;
- margin-top: 2rem;
- margin-bottom: 0;
- }
-
- .avatar {
- width: 1em;
- height: 1em;
- margin-right: 0.5em;
- border-radius: 50%;
- overflow:hidden;
-
- &-img {
- display: block;
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
- }
-
- .count {
- font-size: 1em;
- display: block;
- text-align: center;
- }
- </style>
- </head>
-
- <body>
- <Nav title={title} />
-
- <main class="wrapper">
- <h2 class="title">
- <div class="avatar"><img class="avatar-img" src={author.image} alt=""}></div>
- {author.name}
- </h2>
- <small class="count">{collection.start + 1}–{collection.end + 1} of {collection.total}</small>
- {collection.data.map((post) => <PostPreview post={post} author={author} />)}
- </main>
-
- <footer>
- <Pagination prevUrl={collection.url.prev} nextUrl={collection.url.next} />
- </footer>
- </body>
-</html>
diff --git a/examples/blog/src/pages/$posts.astro b/examples/blog/src/pages/$posts.astro
deleted file mode 100644
index 0975e8007..000000000
--- a/examples/blog/src/pages/$posts.astro
+++ /dev/null
@@ -1,83 +0,0 @@
----
-import MainHead from '../components/MainHead.astro';
-import Nav from '../components/Nav.astro';
-import PostPreview from '../components/PostPreview.astro';
-import Pagination from '../components/Pagination.astro';
-
-// page
-let title = 'Don’s Blog';
-let description = 'An example blog on Astro';
-let canonicalURL = Astro.request.canonicalURL;
-
-// collection
-import authorData from '../data/authors.json';
-let { collection } = Astro.props;
-export async function createCollection() {
- return {
- /** Load posts, sort newest -> oldest */
- async data() {
- let allPosts = Astro.fetchContent('./post/*.md');
- allPosts.sort((a, b) => new Date(b.date) - new Date(a.date));
- return allPosts;
- },
- /** Set page size */
- pageSize: 2,
- /** Generate RSS feed (only for main /posts/ feed) */
- rss: {
- title: 'Don’s Blog',
- description: 'An example blog on Astro',
- customData: `<language>en-us</language>`,
- item: (item) => ({
- title: item.title,
- description: item.description,
- link: item.url,
- pubDate: item.date,
- }),
- }
- };
-}
----
-
-<html>
- <head>
- <title>{title}</title>
- <MainHead
- title={title}
- description={description}
- image={collection.data[0].image}
- canonicalURL={canonicalURL}
- prev={collection.url.prev}
- next={collection.url.next}
- />
-
- <style lang="scss">
- .title {
- font-size: 3em;
- letter-spacing: -0.04em;
- margin-top: 2rem;
- margin-bottom: 0;
- text-align: center;
- }
-
- .count {
- font-size: 1em;
- display: block;
- text-align: center;
- }
- </style>
- </head>
-
- <body>
- <Nav title={title} />
-
- <main class="wrapper">
- <h2 class="title">All Posts</h2>
- <small class="count">{collection.start + 1}–{collection.end + 1} of {collection.total}</small>
- {collection.data.map((post) => <PostPreview post={post} author={authorData[post.author]} />)}
- </main>
-
- <footer>
- <Pagination prevUrl={collection.url.prev} nextUrl={collection.url.next} />
- </footer>
- </body>
-</html>
diff --git a/examples/blog/src/pages/about.astro b/examples/blog/src/pages/about.astro
deleted file mode 100644
index d7a219057..000000000
--- a/examples/blog/src/pages/about.astro
+++ /dev/null
@@ -1,63 +0,0 @@
----
-import MainHead from '../components/MainHead.astro';
-import Nav from '../components/Nav.astro';
-
-let title = "About";
----
-<html>
- <head>
- <MainHead
- title={title}
- canonicalURL={Astro.request.canonicalURL}
- />
- <style lang="scss">
-
- .text {
- padding-bottom: 6rem;
-
- p {
- font-size: 1.2em;
- line-height: 2;
- margin-top: 2em;
- margin-bottom: 2em;
- }
- }
-
- .hero {
- display: block;
- height: 16rem;
- overflow: hidden;
- margin: 4rem 0;
-
- &-img {
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
- }
-
- .title {
- font-size: 3em;
- letter-spacing: -0.04em;
- margin-top: 2rem;
- margin-bottom: 0;
- text-align: center;
- }
- </style>
- </head>
- <body>
- <Nav title={title} />
-
- <main class="wrapper">
- <h2 class="title">{title}</h2>
- <div class="hero">
- <img class="hero-img" src="/images/chapter-01.jpg" alt="">
- </div>
- <div class="text">
- <p>The book cover and spine above and the images which follow were not part of the original Ormsby translation—they are taken from the 1880 edition of J. W. Clark, illustrated by Gustave Doré. Clark in his edition states that, “The English text of ‘Don Quixote’ adopted in this edition is that of Jarvis, with occasional corrections from Motteaux.”</p>
- <p>See in the introduction below John Ormsby’s critique of both the Jarvis and Motteaux translations. It has been elected in the present Project Gutenberg edition to attach the famous engravings of Gustave Doré to the Ormsby translation instead of the Jarvis/Motteaux. The detail of many of the Doré engravings can be fully appreciated only by utilizing the “Full Size” button to expand them to their original dimensions. Ormsby in his Preface has criticized the fanciful nature of Doré’s illustrations; others feel these woodcuts and steel engravings well match Quixote’s dreams.</p>
- </div>
- </main>
-
- </body>
-</html>
diff --git a/examples/blog/src/pages/index.astro b/examples/blog/src/pages/index.astro
index a4407378c..c61340fdd 100644
--- a/examples/blog/src/pages/index.astro
+++ b/examples/blog/src/pages/index.astro
@@ -1,43 +1,77 @@
---
-import MainHead from '../components/MainHead.astro';
-import Nav from '../components/Nav.astro';
-import PostPreview from '../components/PostPreview.astro';
-import Pagination from '../components/Pagination.astro';
-
-// page
-let title = 'Don’s Blog';
-let description = 'An example blog on Astro';
-
-// collection
-// note: we want to show first 3 posts here, but we don’t want to paginate at /1, /2, /3, etc.
-// so we show a preview of posts here, but actually paginate from $posts.astro
-import authorData from '../data/authors.json';
-
-let allPosts = Astro.fetchContent('./post/*.md');
-allPosts.sort((a, b) => new Date(b.date) - new Date(a.date));
-let firstPage = allPosts.slice(0, 2);
+import BaseHead from '../components/BaseHead.astro';
+import BlogHeader from '../components/BlogHeader.astro';
+import BlogPostPreview from '../components/BlogPostPreview.astro';
+
+let title = 'Example Blog';
+let description = 'The perfect starter for your perfect blog.';
+let permalink = 'https://example.com/';
+
+let allPosts = Astro.fetchContent('./posts/*.md');
+allPosts = allPosts.sort((a, b) => new Date(b.date) - new Date(a.date));
---
<html>
<head>
- <title>{title}</title>
- <MainHead
- title={title}
- description={description}
- image={firstPage[0].image}
- canonicalURL={Astro.request.canonicalURL.href}
- />
- </head>
+ <BaseHead title={title} description={description} permalink={permalink} />
+ <link rel="stylesheet" href="/blog.css" />
- <body>
- <Nav />
+ <style>
+ body {
+ width: 100%;
+ display: grid;
+ grid-template-rows: 3.5rem 1fr;
+ --gutter: 0.5rem;
+ --doc-padding: 2rem;
+ }
+
+ header {
+ width: 100%;
+ height: 100%;
+ background-color: var(--theme-bg-offset);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .content {
+ margin-top: 4rem;
+ margin-bottom: 8rem;
+ }
- <main class="wrapper">
- {firstPage.map((post) => <PostPreview post={post} author={authorData[post.author]} />)}
- </main>
+ .content :global(main > * + *) {
+ margin-top: 1rem;
+ }
- <footer>
- <Pagination nextUrl="/posts/2" />
- </footer>
+ .intro {
+ padding-bottom: 4rem;
+ margin-bottom: 2rem;
+ border-bottom: 4px solid var(--theme-divider);
+ }
+
+ .intro > * {
+ margin: 0;
+ }
+
+ .latest {
+ font-size: 2.5rem;
+ font-weight: 700;
+ }
+ </style>
+ </head>
+
+ <body>
+ <BlogHeader />
+ <div class="layout">
+ <article class="content">
+ <section class="intro">
+ <h1 class="latest">{title}</h1>
+ <p>{description}</p>
+ </section>
+ <section>
+ {allPosts.map(p => <BlogPostPreview post={p} />)}
+ </section>
+ </article>
+ </div>
</body>
</html>
diff --git a/examples/blog/src/pages/post/chapter-i.md b/examples/blog/src/pages/post/chapter-i.md
deleted file mode 100644
index 9a6fa14ea..000000000
--- a/examples/blog/src/pages/post/chapter-i.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-layout: ../../layouts/post.astro
-title: Chapter I
-tag: movie
-date: 2021-05-17
-image: /images/chapter-01.jpg
-author: don
-description: Which Treats of the Character and Pursuits of the Famous Gentleman Don Quixote of La Mancha
----
-
-In a village of La Mancha, the name of which I have no desire to call to mind, there lived not long since one of those gentlemen that keep a lance in the lance-rack, an old buckler, a lean hack, and a greyhound for coursing. An olla of rather more beef than mutton, a salad on most nights, scraps on Saturdays, lentils on Fridays, and a pigeon or so extra on Sundays, made away with three-quarters of his income. The rest of it went in a doublet of fine cloth and velvet breeches and shoes to match for holidays, while on week-days he made a brave figure in his best homespun. He had in his house a housekeeper past forty, a niece under twenty, and a lad for the field and market-place, who used to saddle the hack as well as handle the bill-hook. The age of this gentleman of ours was bordering on fifty; he was of a hardy habit, spare, gaunt-featured, a very early riser and a great sportsman. They will have it his surname was Quixada or Quesada (for here there is some difference of opinion among the authors who write on the subject), although from reasonable conjectures it seems plain that he was called Quexana. This, however, is of but little importance to our tale; it will be enough not to stray a hair’s breadth from the truth in the telling of it.
-
-You must know, then, that the above-named gentleman whenever he was at leisure (which was mostly all the year round) gave himself up to reading books of chivalry with such ardour and avidity that he almost entirely neglected the pursuit of his field-sports, and even the management of his property; and to such a pitch did his eagerness and infatuation go that he sold many an acre of tillageland to buy books of chivalry to read, and brought home as many of them as he could get. But of all there were none he liked so well as those of the famous Feliciano de Silva’s composition, for their lucidity of style and complicated conceits were as pearls in his sight, particularly when in his reading he came upon courtships and cartels, where he often found passages like “the reason of the unreason with which my reason is afflicted so weakens my reason that with reason I murmur at your beauty;” or again, “the high heavens, that of your divinity divinely fortify you with the stars, render you deserving of the desert your greatness deserves.” Over conceits of this sort the poor gentleman lost his wits, and used to lie awake striving to understand them and worm the meaning out of them; what Aristotle himself could not have made out or extracted had he come to life again for that special purpose. He was not at all easy about the wounds which Don Belianis gave and took, because it seemed to him that, great as were the surgeons who had cured him, he must have had his face and body covered all over with seams and scars. He commended, however, the author’s way of ending his book with the promise of that interminable adventure, and many a time was he tempted to take up his pen and finish it properly as is there proposed, which no doubt he would have done, and made a successful piece of work of it too, had not greater and more absorbing thoughts prevented him.
diff --git a/examples/blog/src/pages/post/chapter-ii.md b/examples/blog/src/pages/post/chapter-ii.md
deleted file mode 100644
index eda406b42..000000000
--- a/examples/blog/src/pages/post/chapter-ii.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-layout: ../../layouts/post.astro
-title: Chapter II
-tag: movie
-date: 2021-05-18
-image: /images/chapter-02.jpg
-author: sancho
-description: Which Treats of the First Sally the Ingenious Don Quixote Made From Home
----
-
-These preliminaries settled, he did not care to put off any longer the execution of his design, urged on to it by the thought of all the world was losing by his delay, seeing what wrongs he intended to right, grievances to redress, injustices to repair, abuses to remove, and duties to discharge. So, without giving notice of his intention to anyone, and without anybody seeing him, one morning before the dawning of the day (which was one of the hottest of the month of July) he donned his suit of armour, mounted Rocinante with his patched-up helmet on, braced his buckler, took his lance, and by the back door of the yard sallied forth upon the plain in the highest contentment and satisfaction at seeing with what ease he had made a beginning with his grand purpose. But scarcely did he find himself upon the open plain, when a terrible thought struck him, one all but enough to make him abandon the enterprise at the very outset. It occurred to him that he had not been dubbed a knight, and that according to the law of chivalry he neither could nor ought to bear arms against any knight; and that even if he had been, still he ought, as a novice knight, to wear white armour, without a device upon the shield until by his prowess he had earned one. These reflections made him waver in his purpose, but his craze being stronger than any reasoning, he made up his mind to have himself dubbed a knight by the first one he came across, following the example of others in the same case, as he had read in the books that brought him to this pass. As for white armour, he resolved, on the first opportunity, to scour his until it was whiter than an ermine; and so comforting himself he pursued his way, taking that which his horse chose, for in this he believed lay the essence of adventures.
-
-Thus setting out, our new-fledged adventurer paced along, talking to himself and saying, “Who knows but that in time to come, when the veracious history of my famous deeds is made known, the sage who writes it, when he has to set forth my first sally in the early morning, will do it after this fashion? ‘Scarce had the rubicund Apollo spread o’er the face of the broad spacious earth the golden threads of his bright hair, scarce had the little birds of painted plumage attuned their notes to hail with dulcet and mellifluous harmony the coming of the rosy Dawn, that, deserting the soft couch of her jealous spouse, was appearing to mortals at the gates and balconies of the Manchegan horizon, when the renowned knight Don Quixote of La Mancha, quitting the lazy down, mounted his celebrated steed Rocinante and began to traverse the ancient and famous Campo de Montiel;’” which in fact he was actually traversing. “Happy the age, happy the time,” he continued, “in which shall be made known my deeds of fame, worthy to be moulded in brass, carved in marble, limned in pictures, for a memorial for ever. And thou, O sage magician, whoever thou art, to whom it shall fall to be the chronicler of this wondrous history, forget not, I entreat thee, my good Rocinante, the constant companion of my ways and wanderings.” Presently he broke out again, as if he were love-stricken in earnest, “O Princess Dulcinea, lady of this captive heart, a grievous wrong hast thou done me to drive me forth with scorn, and with inexorable obduracy banish me from the presence of thy beauty. O lady, deign to hold in remembrance this heart, thy vassal, that thus in anguish pines for love of thee.”
-
-So he went on stringing together these and other absurdities, all in the style of those his books had taught him, imitating their language as well as he could; and all the while he rode so slowly and the sun mounted so rapidly and with such fervour that it was enough to melt his brains if he had any. Nearly all day he travelled without anything remarkable happening to him, at which he was in despair, for he was anxious to encounter someone at once upon whom to try the might of his strong arm.
diff --git a/examples/blog/src/pages/post/chapter-iii.md b/examples/blog/src/pages/post/chapter-iii.md
deleted file mode 100644
index 0b799bc61..000000000
--- a/examples/blog/src/pages/post/chapter-iii.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-layout: ../../layouts/post.astro
-title: Chapter III
-tag: movie
-date: 2021-05-19
-image: /images/chapter-03.jpg
-author: don
-description: Wheren is Related the Droll Way in which Don Quixote Had Himself Dubbed a Knight
----
-
-Harassed by this reflection, he made haste with his scanty pothouse supper, and having finished it called the landlord, and shutting himself into the stable with him, fell on his knees before him, saying, “From this spot I rise not, valiant knight, until your courtesy grants me the boon I seek, one that will redound to your praise and the benefit of the human race.” The landlord, seeing his guest at his feet and hearing a speech of this kind, stood staring at him in bewilderment, not knowing what to do or say, and entreating him to rise, but all to no purpose until he had agreed to grant the boon demanded of him. “I looked for no less, my lord, from your High Magnificence,” replied Don Quixote, “and I have to tell you that the boon I have asked and your liberality has granted is that you shall dub me knight to-morrow morning, and that to-night I shall watch my arms in the chapel of this your castle; thus to-morrow, as I have said, will be accomplished what I so much desire, enabling me lawfully to roam through all the four quarters of the world seeking adventures on behalf of those in distress, as is the duty of chivalry and of knights-errant like myself, whose ambition is directed to such deeds.”
-
-The landlord, who, as has been mentioned, was something of a wag, and had already some suspicion of his guest’s want of wits, was quite convinced of it on hearing talk of this kind from him, and to make sport for the night he determined to fall in with his humour. So he told him he was quite right in pursuing the object he had in view, and that such a motive was natural and becoming in cavaliers as distinguished as he seemed and his gallant bearing showed him to be; and that he himself in his younger days had followed the same honourable calling, roaming in quest of adventures in various parts of the world, among others the Curing-grounds of Malaga, the Isles of Riaran, the Precinct of Seville, the Little Market of Segovia, the Olivera of Valencia, the Rondilla of Granada, the Strand of San Lucar, the Colt of Cordova, the Taverns of Toledo, and divers other quarters, where he had proved the nimbleness of his feet and the lightness of his fingers, doing many wrongs, cheating many widows, ruining maids and swindling minors, and, in short, bringing himself under the notice of almost every tribunal and court of justice in Spain; until at last he had retired to this castle of his, where he was living upon his property and upon that of others; and where he received all knights-errant of whatever rank or condition they might be, all for the great love he bore them and that they might share their substance with him in return for his benevolence. He told him, moreover, that in this castle of his there was no chapel in which he could watch his armour, as it had been pulled down in order to be rebuilt, but that in a case of necessity it might, he knew, be watched anywhere, and he might watch it that night in a courtyard of the castle, and in the morning, God willing, the requisite ceremonies might be performed so as to have him dubbed a knight, and so thoroughly dubbed that nobody could be more so. He asked if he had any money with him, to which Don Quixote replied that he had not a farthing, as in the histories of knights-errant he had never read of any of them carrying any. On this point the landlord told him he was mistaken; for, though not recorded in the histories, because in the author’s opinion there was no need to mention anything so obvious and necessary as money and clean shirts, it was not to be supposed therefore that they did not carry them, and he might regard it as certain and established that all knights-errant (about whom there were so many full and unimpeachable books) carried well-furnished purses in case of emergency, and likewise carried shirts and a little box of ointment to cure the wounds they received. For in those plains and deserts where they engaged in combat and came out wounded, it was not always that there was someone to cure them, unless indeed they had for a friend some sage magician to succour them at once by fetching through the air upon a cloud some damsel or dwarf with a vial of water of such virtue that by tasting one drop of it they were cured of their hurts and wounds in an instant and left as sound as if they had not received any damage whatever. But in case this should not occur, the knights of old took care to see that their squires were provided with money and other requisites, such as lint and ointments for healing purposes; and when it happened that knights had no squires (which was rarely and seldom the case) they themselves carried everything in cunning saddle-bags that were hardly seen on the horse’s croup, as if it were something else of more importance, because, unless for some such reason, carrying saddle-bags was not very favourably regarded among knights-errant. He therefore advised him (and, as his godson so soon to be, he might even command him) never from that time forth to travel without money and the usual requirements, and he would find the advantage of them when he least expected it.
diff --git a/examples/blog/src/pages/posts/introducing-astro.md b/examples/blog/src/pages/posts/introducing-astro.md
new file mode 100644
index 000000000..54705e8ac
--- /dev/null
+++ b/examples/blog/src/pages/posts/introducing-astro.md
@@ -0,0 +1,90 @@
+---
+title: 'Introducing Astro: Ship Less JavaScript'
+description: "We're excited to announce Astro as a new way to build static websites and deliver lightning-fast performance without sacrificing a modern developer experience."
+publishDate: 'Tuesday, June 8 2021'
+author: 'fred'
+heroImage: '/social.jpg'
+layout: '../../layouts/BlogPost.astro'
+---
+
+There's a simple secret to building a faster website — *just ship less*.
+
+Unfortunately, modern web development has been trending in the opposite direction—towards *more.* More JavaScript, more features, more moving parts, and ultimately more complexity needed to keep it all running smoothly.
+
+Today I'm excited to publicly share Astro: a new kind of static site builder that delivers lightning-fast performance with a modern developer experience. To design Astro, we borrowed the best parts of our favorite tools and then added a few innovations of our own, including:
+
+- **Bring Your Own Framework (BYOF):** Build your site using React, Svelte, Vue, Preact, web components, or just plain ol' HTML + JavaScript.
+- **100% Static HTML, No JS:** Astro renders your entire page to static HTML, removing all JavaScript from your final build by default.
+- **On-Demand Components:** Need some JS? Astro can automatically hydrate interactive components when they become visible on the page. If the user never sees it, they never load it.
+- **Fully-Featured:** Astro supports TypeScript, Scoped CSS, CSS Modules, Sass, Tailwind, Markdown, MDX, and any of your favorite npm packages.
+- **SEO Enabled:** Automatic sitemaps, RSS feeds, pagination and collections take the pain out of SEO and syndication.
+
+This post marks the first public beta release of Astro. **Missing features and bugs are still to be expected at this early stage.** There are still some months to go before an official 1.0 release, but there are already several fast sites built with Astro in production today. We would love your early feedback as we move towards a v1.0 release later this year.
+
+<Note>
+ To learn more about Astro and start building your first site, check out [the project README.](https://github.com/snowpackjs/astro#-guides)
+</Note>
+
+## Getting Started
+
+Starting a new project in Astro is easy:
+
+```shell
+# create your project
+mkdir new-project-directory
+cd new-project-directory
+npm init astro
+
+# install your dependencies
+npm install
+
+# start the dev server and open your browser
+npm start
+```
+
+> To learn more about Astro and start building your first site, check out [the project README.](https://github.com/snowpackjs/astro#-guides).
+
+
+## How Astro Works
+
+Astro works a lot like a static site generator. If you have ever used Eleventy, Hugo, or Jekyll (or even a server-side web framework like Rails, Laravel, or Django) then you should feel right at home with Astro.
+
+In Astro, you compose your website using UI components from your favorite JavaScript web framework (React, Svelte, Vue, etc). Astro renders your entire site to static HTML during the build. The result is a fully static website with all JavaScript removed from the final page. No monolithic JavaScript application required, just static HTML that loads as fast as possible in the browser regardless of how many UI components you used to generate it.
+
+Of course, sometimes client-side JavaScript is inevitable. Image carousels, shopping carts, and auto-complete search bars are just a few examples of things that require some JavaScript to run in the browser. This is where Astro really shines: When a component needs some JavaScript, Astro only loads that one component (and any dependencies). The rest of your site continues to exist as static, lightweight HTML.
+
+In other full-stack web frameworks this level of per-component optimization would be impossible without loading the entire page in JavaScript, delaying interactivity. In Astro, this kind of [partial hydration](https://addyosmani.com/blog/rehydration/) is built into the tool itself.
+
+You can even [automatically defer components](https://codepen.io/jonneal/full/ZELvMvw) to only load once they become visible on the page with the `:visible` modifier.
+
+This new approach to web architecture is called [islands architecture](https://jasonformat.com/islands-architecture/). We didn't coin the term, but Astro may have perfected the technique. We are confident that an HTML-first, JavaScript-only-as-needed approach is the best solution for the majority of content-based websites.
+
+> To learn more about Astro and start building your first site, check out [the project README.](https://github.com/snowpackjs/astro#-guides)
+
+## Embracing the Pit of Success
+
+<BlockQuote author="Jeff Atwood" source="Falling Into The Pit of Success" sourceHref="https://blog.codinghorror.com/falling-into-the-pit-of-success/">
+ A well-designed system makes it easy to do the right things and annoying (but not impossible) to do the wrong things
+</BlockQuote>
+
+Poor performance is often framed as a failure of the developer, but we respectfully disagree. In many cases, poor performance is a failure of tooling. It should be difficult to build a slow website.
+
+Astro's main design principle is to lead developers into what [Rico Mariani](https://twitter.com/ricomariani) dubbed "the pit of success". It is our goal to build every site "fast by default" while also delivering a familiar, modern developer experience.
+
+By building your site to static HTML by default, Astro makes it difficult (but never impossible 😉) to build a slow site.
+
+## Long-Term Sustainability
+
+Astro is built by the team of open source developers behind [Snowpack](https://snowpack.dev) and [Skypack](https://skypack.dev), with additional contributions from the community.
+
+**Astro is and always will be free.** It is an open source project released under the [MIT license](https://github.com/snowpackjs/astro/blob/main/LICENSE).
+
+We care deeply about building a more sustainable future for open source software. At the same time, we need to support Astro's development long-term. This requires money (donations alone aren't enough.)
+
+We're inspired by the early success of projects like [Tailwind](https://tailwindcss.com/), [Rome](https://rome.tools/), [Remix](https://remix.run/), [Ionic](https://ionicframework.com/), and others who are experimenting with long-term financial sustainability on top of Open Source. Over the next year we'll be exploring how we can create a sustainable business to support a 100% free, open source Astro for years to come.
+
+If your company is as excited about Astro as we are, [we'd love to hear from you.](https://astro.build/chat)
+
+Finally, I'd like to give a **HUGE** thanks to the 300+ developers who joined our earliest private beta. Your feedback has been essential in shaping Astro into the tool it is today. If you're interested in getting involved (or just following along with development) please [join us on Discord.](https://astro.build/chat)
+
+> To learn more about Astro and start building your first site, check out [the project README.](https://github.com/snowpackjs/astro#-guides) \ No newline at end of file