Create a Headings Component for an Astro Project with Svelte
- astro
- components
- content delivery
- headings
- open source
- responsive design
- scalability
- seo optimization
- svelte
- web performance
Markdown Headings and SEO Optimization
Heading tags are the standard way to structure markdown content, playing a crucial role in SEO optimization by improving content delivery and ranking in search engines. Astro simplifies parsing markdown out of the box and seamlessly handles MDX content with its first-party MDX integration. This ensures that your content is both scalable and optimized for performance.
I enjoy using Svelte to create interactive and efficient components. Astro enhances this experience with its first-party Svelte integration, allowing for the development of highly responsive designs and mobile-first interfaces.
Here’s how I created a Headings component to parse all the headings from a markdown file or a list of headings and display them as clickable links, enhancing both user experience and SEO.
Headings Component for Enhanced Content Delivery
First, we will create a Headings.svelte
component. This component is designed for flexibility, allowing it to be used in multiple contexts by accepting either an imported file
or a list of headings
directly.
Each .md
or .mdx
file can be imported using Astro’s built-in methods, which we’ll implement in the next section. Imported files contain various data points that are essential for key management and performance optimization, including:
url
: The path to the file.headings
: A list of heading objects.
Each heading object in headings
includes keys such as:
depth
: Indicates the level of the heading (e.g.,<h2>
has a depth of 2).slug
: The automatically generated ID used for linking.
<!-- Headings.svelte -->
<script>
// Props - accepts entire file or just the headings
export let headings = [];
export let file = {};
// Check if the file has any keys
const isFile = Object.keys(file).length > 0;
// If the file has keys, use the headings from the file instead of the headings prop
if (isFile) {
headings = file.getHeadings();
}
</script>
<!-- Iterate through each heading -->
{#each headings as heading}
<div>
<!--
Prefix each heading with a # and indent accordingly
with CSS classes based on heading.depth for responsive design
-->
<span
class:ml-3={heading.depth === 3}
class:ml-6={heading.depth === 4}
class:ml-9={heading.depth === 5}
class:ml-12={heading.depth === 6}
>
#
</span>
<!--
Determine the link based on whether a file is passed in:
- If a file is passed, link to the full path.
- If only headings are passed, link to the specific ID on the page.
-->
<a href={isFile ? `${file.url}#${heading.slug}` : `#${heading.slug}`}>
{heading.text}
</a>
</div>
{/each}
<style>
div {
display: flex;
margin-bottom: 0.5rem;
}
span {
margin-left: 0.25rem;
}
.ml-3 {
margin-left: 0.75rem;
}
.ml-6 {
margin-left: 1.5rem;
}
.ml-9 {
margin-left: 2.25rem;
}
.ml-12 {
margin-left: 3rem;
}
</style>
Implementing the Headings Component
We can now integrate this component into our markdown layouts by providing headings
, or by passing the entire file
through the file
prop in another page.
Markdown Layout for SEO-Friendly Headings
Create a layout for posts that displays the headings
from your markdown file, enhancing content delivery and user navigation.
---
# @layouts/post/Post.astro
import Headings from "@components/Headings.svelte";
const { headings } = Astro.props;
---
<Headings headings={headings} />
<hr />
<slot />
Use this layout in your markdown file located in src/pages/posts/
:
---
layout: "@layouts/post/Post.astro"
---
# Heading 1
## Heading 2
### Heading 3
Importing Headings in Other Pages for Enhanced SEO
To display headings as a preview outside of the page itself (e.g., on a homepage or a sidebar), you can import your files from src/pages/posts
using Astro’s glob method. This approach leverages scalability and performance optimization.
---
# src/pages/index.astro
import Headings from "@components/Headings.svelte";
const posts = await Astro.glob("./posts/*");
---
<!-- Pass the first post into the component -->
<Headings file={posts[0]} />
Performance and SEO Benefits
Astro’s build-time rendering ensures that the Headings
component is delivered to the client as optimized HTML and CSS with no additional JavaScript, enhancing web performance and scalability. This approach reduces energy consumption and aligns with sustainability and green practices by minimizing resource usage.
I’ve thoroughly enjoyed using Astro to create this blog. The first-party .mdx
integration and Astro.glob
method facilitate efficient content delivery and SEO optimization, making it an excellent choice for developers focused on responsive design and performance. I highly recommend Astro to others building static sites who prioritize SEO benefits and user experience.
Thanks for reading!