Skip to content

Commit

Permalink
feat: add canonical link setup (#266)
Browse files Browse the repository at this point in the history
## Why?

This pull request automates the addition of the canonical meta tag to
every page within the website using the `<link/>` tag.

## How?

- For the docs pages, make sure the slugs passed down to the layout code
to ensure appropriation of the URLs.
- Used the custom function ` generateCanonicalUrl(baseUrl: string,
slug?: string)` to handle canonical URLs for the base layouts

## Tickets?

- [Self-referencing Canonical
tags](https://linear.app/fleekxyz/issue/MKTG-234/self-referencing-canonical-tags)

## Contribution checklist?

- [x] The commit messages are detailed
- [x] The `build` command runs locally
- [x] Assets or static content are linked and stored in the project
- [x] Document filename is named after the slug
- [x] You've reviewed spelling using a grammar checker
- [x] For documentation, guides or references, you've tested the
commands and steps
- [x] You've done enough research before writing

## Security checklist?

- [x] Sensitive data has been identified and is being protected properly
- [x] Injection has been prevented (parameterized queries, no eval or
system calls)
- [x] The Components are escaping output (to prevent XSS)

---------

Co-authored-by: Helder Oliveira <[email protected]>
  • Loading branch information
tobySolutions and heldrida authored Oct 16, 2024
1 parent e0c7cd1 commit eb1205e
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/layouts/BaseHtml.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Announcement } from '@components/Announcement';
import Footer from '@components/Footer';
import { Navbar } from '@components/Navbar';
import SupportMenu from '@components/Support/SupportMenu';
import { generateCanonicalUrl } from '@utils/generateCanonicalUrl';
interface Props {
title: string;
Expand All @@ -23,6 +24,9 @@ interface Props {
const { ogMeta } = Astro.props;
const baseUrl = getSiteUrl();
const hasSecondaryMenu = hasSecondaryMenuItem(Astro.url.pathname);
const contentSlug = ogMeta?.slug || Astro.url.pathname;
const canonicalUrl = generateCanonicalUrl(contentSlug);
---

<!doctype html>
Expand All @@ -31,6 +35,7 @@ const hasSecondaryMenu = hasSecondaryMenuItem(Astro.url.pathname);
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<link rel="canonical" href={`${canonicalUrl}`} />
<link rel="sitemap" href="/sitemap-index.xml" />
<link
rel="preload"
Expand Down
9 changes: 7 additions & 2 deletions src/layouts/DocPage.astro
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ import { Announcement } from '@components/Announcement';
type Props = {
title: string;
description: string;
pageSlug: string;
headings: MarkdownHeading[];
prevItem: DocsLink | null;
nextItem: DocsLink | null;
};
const { title, description, headings, prevItem, nextItem } = Astro.props;
const { title, description, headings, prevItem, nextItem, pageSlug } =
Astro.props;
const {
collection,
id,
Expand Down Expand Up @@ -76,9 +79,11 @@ const indexNameDocs = import.meta.env.PUBLIC_MEILISEARCH_INDEX_DOCS;
// TODO: Fails after prod build
const isHome = Astro.url.pathname === '/docs';
const isDocsHomepage = data.slug === 'index' && pageSlug === 'index';
const slug = generateFullSlug({
basePath: settings.site.metadata.docs.slug,
slug: data.slug === 'index' ? '' : data.slug,
slug: isDocsHomepage ? '' : pageSlug,
});
const image = settings.site.metadata.docs.image;
Expand Down
4 changes: 4 additions & 0 deletions src/layouts/DocsHtml.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import settings from '@base/settings.json';
import { Toaster } from 'react-hot-toast';
import { Navbar } from '@components/Navbar';
import PostHog from '@components/PostHog.astro';
import { generateCanonicalUrl } from '@utils/generateCanonicalUrl';
interface Props {
title: string;
Expand All @@ -18,6 +19,8 @@ interface Props {
const { ogMeta } = Astro.props;
const baseUrl = getSiteUrl();
const docsPageSlug = ogMeta?.slug || Astro.url.pathname;
const canonicalUrl = generateCanonicalUrl(docsPageSlug);
---

<!doctype html>
Expand All @@ -27,6 +30,7 @@ const baseUrl = getSiteUrl();
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<link rel="sitemap" href="/sitemap-index.xml" />
<link rel="canonical" href={`${canonicalUrl}`} />
<link
rel="preload"
href="/fonts/atyp/AtypDisplay-Regular.woff2"
Expand Down
4 changes: 4 additions & 0 deletions src/layouts/LandingPageHtml.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import '@styles/globals.css';
import { getSiteUrl } from '@utils/url';
import settings from '@base/settings.json';
import PostHog from '@components/PostHog.astro';
import { generateCanonicalUrl } from '@utils/generateCanonicalUrl';
const baseUrl = getSiteUrl();
const canonicalUrl = generateCanonicalUrl();
---

<!doctype html>
Expand All @@ -14,6 +17,7 @@ const baseUrl = getSiteUrl();
name="viewport"
content="width=device-width, height=device-height, initial-scale=1, viewport-fit=cover"
/>
<link rel="canonical" href={`${canonicalUrl}`} />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<link rel="sitemap" href="/sitemap-index.xml" />
<link
Expand Down
2 changes: 2 additions & 0 deletions src/pages/docs/[...slug].astro
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export async function getStaticPaths() {
const { entry, prevItem, nextItem, currentCategory } = Astro.props;
const { Content, headings } = await entry.render();
const title = handlePageTitle('Docs');
const pageSlug = entry.slug;
function handlePageTitle(collection: string) {
if (entry.data.title && currentCategory !== 'root') {
Expand All @@ -81,6 +82,7 @@ function handlePageTitle(collection: string) {
<DocPageLayout
title={title}
description={entry.data.desc || ''}
pageSlug={pageSlug}
headings={headings}
prevItem={prevItem}
nextItem={nextItem}
Expand Down
2 changes: 2 additions & 0 deletions src/pages/docs/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ const { Content, headings } = await entry.render();
const title = entry.data.title || settings.site.metadata.docs.title;
const description = entry.data.desc || settings.site.metadata.docs.description;
const pageSlug = entry.slug;
---

<Layout
title={title}
description={description}
headings={headings}
prevItem={null}
pageSlug={pageSlug}
nextItem={nextItem}
>
<Content />
Expand Down
15 changes: 15 additions & 0 deletions src/utils/generateCanonicalUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getSiteUrl } from './url';

const BASE_URL = getSiteUrl();

export function generateCanonicalUrl(slug?: string) {
if (!slug) return `${BASE_URL}/`;

const sanitizedSlug = slug
.trim()
.split('/')
.filter((item) => item)
.join('/');

return `${BASE_URL}/${sanitizedSlug}/`;
}

0 comments on commit eb1205e

Please sign in to comment.