npx create-astro@latest
. Also, you should initialize github repo since we will be deploying to vercel.npx astro add tailwind
to add tailwind to our project.npm install -D @tailwindcss/typography
to add the typography library. We will be using it to style the posts.tailwind.config.mjs
, add require('@tailwindcss/typography')
to the plugin list to enable it.API Access
, copy the Content API
url. Go to the project root folder, create a .env
file with the content HYGRAPH_ENDPOINT=[YOUR_URL]
The src
folder should look like this:
src/
└── pages/
│ └── index.astro
└── env.d.ts
layouts
folder and a file Layout.astro
inside of it---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<slot />
</body>
</html>
util
folder with a getPost.ts
file in it. We will be using it to fetch the posts from Hygraph.type Post = {
title: string;
slug: string;
date: string;
content: {
html: string;
};
coverImage: {
url: string;
width: number;
height: number;
altText: string;
};
};
export default async (slug?: string) => {
const query = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `
{
posts(where: {${slug ? `slug: "${slug}"` : ''}}) {
title
slug
date
content {
html
}
coverImage {
url
width
height
altText
}
}
}`,
}),
};
const response = await fetch(import.meta.env.HYGRAPH_ENDPOINT, query);
const json = await response.json();
const posts: Post[] = json.data.posts;
return posts;
};
pages
folder, create a post
folder with file [post].astro
in it. It uses dynamic routing and shows all posts fetched from Hygraph.---
import type { GetStaticPaths } from "astro";
import getPost from "../../util/getPost";
import Layout from "../../layouts/Layout.astro";
type Props = {
post: string;
};
export const getStaticPaths = (async () => {
const posts = await getPost();
return posts.map((post) => {
return {
params: {
post: post.slug,
},
};
});
}) satisfies GetStaticPaths;
const { post } = Astro.params;
const posts = await getPost(post);
const currentPost = posts.find((fetchedPost) => fetchedPost.slug === post)!;
---
<Layout title={currentPost.title}>
<main class="prose mx-auto my-12">
<h1>{currentPost.title}</h1>
<div>{currentPost.date}</div>
<div class="flex justify-center">
<img
class="object-contain h-[400px] w-auto"
src={currentPost.coverImage.url}
alt={currentPost.coverImage.altText}
width={currentPost.coverImage.width}
height={currentPost.coverImage.height}
/>
</div>
<article set:html={currentPost.content.html} />
</main>
</Layout>
index.astro
:---
import Layout from "../layouts/Layout.astro"
import getPost from "../util/getPost"
const posts = await getPost();
---
<Layout title="Main Page">
<div class="prose mx-auto my-16">
<h1>Blog</h1>
{
posts.map((post) => (
<div>
<h2>
<a href={`/post/${post.slug}`}>{post.title}</a>
</h2>
</div>
))
}
</div>
</Layout>
Your src
folder should now look like this:
src/
└── layouts/
│ └── Layout.astro
├── pages
│ └── post
│ └── [post].astro
├── util
│ └── getPost.ts
└── env.d.ts
You can now run npm run dev
to see the blog is working already!
Click on any of the post:
As you can see, the site already looks pretty nice even though we barely styled it, thanks to the typography plugin from tailwind.
And that is it! All that is left is to deploy and create a webhook.
First, commit all the changes to a github repo. Then create a new project in vercel and import the git repo you just created. Make sure that you add in the HYGRAPH_ENDPOINT environment variable as well.
If everything goes accordingly, you should see deploy success.
Last but not least, the crucial part for most headless CMS is to add a webhook so any update to the content will trigger a rebuild.
Go to Vercel Settings > Git and Deploy Hooks, create a hook with your github branch (main or origin in most cases).
Copy the url and go to Hygraph dashboard. In Webhooks, choose Add Webhook
.
Voila, your blog site is set and ready. Any time you make a change to the content, the webhook will trigger and vercel will rebuild your site with the newly updated data.
There are endless possibilities with Astro and headless CMS. Not only can you generate static sites with Astro, you can also integrate it with other frameworks and optionally do Server-side Rendering, making Astro such a powerful framework. If you are interested to learn more about Astro and Hygraph and what you can do with them, feel free to dig deeper into their docs and you might find yourself enjoy working them the more you learn about them.
Last updated: Jan 19 2024