The first thing we can do to improve our navigation is to add a class to set different styles for it when it's the current page we're on. We can do this by comparing the URL of the page we're outputting with the current page we're on using Astro.url
. In our Nav component, update the map
function to check this:
{navPages.map(page =>
<a
href={page.url}
class={(Astro.url.pathname === page.url) && 'is_active'}
>
{page.title}
</a>
)}
We can also improve the accessibility of the current link by correctly setting the aria-current
attribute to 'page' when we set the link's class to active too.
{navPages.map(page =>
<a
href={page.url}
class={(Astro.url.pathname === page.url) && 'is_active'}
aria-current={(Astro.url.pathname === page.url) ? 'page' : 'false'}
>
{page.title}
</a>
)}
Social sharing metadata
Open up our layout template and let's add the missing stuff. Firstly, we need to create a couple of new page variables in the frontmatter and then populate all the required Open Graph and X (previously Twitter) Twitter cards meta elements.
---
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import Nav from '../components/Nav.astro';
const { title, description } = Astro.props;
const xhandle = "MySexyAstro";
const author = "My Sexy Astro Site";
---
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>{title} | My Sexy Astro Site</title>
<meta property="og:site_name" content="My Sexy Astro Site">
<meta property="og:title" content={title}>
<meta property="og:description" content={description}>
<meta property="og:type" content="website">
<meta property="og:image" content={`${Astro.site}img/social/sharer.jpg`}>
<meta property="og:image:width" content="1280">
<meta property="og:image:height" content="800">
<meta property="og:image:alt" content={title} />
<meta property="og:url" content={Astro.url}>
<meta property="article:author" content={author} />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content={`@${xhandle}`}>
<meta name="twitter:creator" content={`@${xhandle}`}>
<link rel="alternate" type="application/rss+xml" title="My Sexy Astro Site" href={`${Astro.site}rss.xml`} />
</head>
<body>
<Header />
<Nav />
<slot />
<Footer />
</body>
</html>
Make sure the image you specify in the og:image
tag exists at that path, and once your site is published you'll see you get a lovely image selected to go with your Facebook/LinkedIn/X/Pinterest/Your Mum's Social Network posts.
If you want to see it in action, you can run them through the Facebook Debugger, the LinkedIn Post Inspector or a more generic tester at OpenGraph.xyz
Wrapping up
We've now got all the basics in place for the site so for completeness here's our final folder structure.
./
├── README.md
├── astro.config.mjs
├── package-lock.json
├── package.json
├── public/
│ └── favicon.svg
├── src/
│ ├── components/
│ │ ├── Footer.astro
│ │ ├── Header.astro
│ │ ├── Nav.astro
│ │ ├── Pagination.astro
│ │ ├── PostDateTime.astro
│ │ ├── PostImage.astro
│ │ ├── PostItem.astro
│ │ ├── TagItem.astro
│ │ └── TagList.astro
│ ├── content/
│ │ ├── config.ts
│ │ └── posts/
│ │ ├── 2024-03-15-my-first-blog-post.mdx
│ │ ├── 2024-03-15-my-second-blog-post.mdx
│ │ └── 2024-03-15-my-third-blog-post.mdx
│ ├── env.d.ts
│ ├── layouts/
│ │ └── Layout.astro
│ └── pages/
│ ├── feed.xml.js
│ ├── index.astro
│ └── posts/
│ ├── [...page].astro
│ ├── [...slug].astro
│ └── tagged/
│ ├── [tag].astro
│ └── index.astro
└── tsconfig.json