mirror of
https://github.com/mikkelsvartveit/astro-personal-website.git
synced 2025-12-22 11:12:38 +00:00
Improve meta tags
This commit is contained in:
parent
bc6ecdc418
commit
22da734d46
10 changed files with 112 additions and 81 deletions
45
src/components/HeadContent.astro
Normal file
45
src/components/HeadContent.astro
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
---
|
||||||
|
import { ViewTransitions } from "astro:transitions";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
title?: string;
|
||||||
|
description?: string;
|
||||||
|
image?: string;
|
||||||
|
themeColor?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title, description, image, themeColor } = Astro.props;
|
||||||
|
|
||||||
|
const fullTitle = title ? `${title} – Mikkel Svartveit` : "Mikkel Svartveit";
|
||||||
|
const defaultDescription =
|
||||||
|
"Hi, I'm Mikkel! I am a Computer Science student from Norway and this is my playground. Here you will find some articles, programming projects, and a small collection of photos I'm proud of.";
|
||||||
|
const defaultImage = "/favicon.png";
|
||||||
|
---
|
||||||
|
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta name="theme-color" content={themeColor ?? "#facc15"} />
|
||||||
|
|
||||||
|
<link rel="icon" href="/favicon.png" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600&family=Source+Code+Pro&family=Source+Serif+Pro:wght@300;400;600&display=swap"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Search engine meta tags -->
|
||||||
|
<title>{fullTitle}</title>
|
||||||
|
<meta name="description" content={description ?? defaultDescription} />
|
||||||
|
|
||||||
|
<!-- Open Graph meta tags -->
|
||||||
|
<meta property="og:title" content={fullTitle} />
|
||||||
|
<meta property="og:description" content={description ?? defaultDescription} />
|
||||||
|
<meta property="og:image" content={image ?? defaultImage} />
|
||||||
|
|
||||||
|
<!-- Twitter meta tags -->
|
||||||
|
<meta name="twitter:card" content="summary" />
|
||||||
|
<meta name="twitter:site" content="@mikkelsvartveit" />
|
||||||
|
<meta name="twitter:title" content={fullTitle} />
|
||||||
|
<meta name="twitter:description" content={description ?? defaultDescription} />
|
||||||
|
<meta name="twitter:image" content={image ?? defaultImage} />
|
||||||
|
|
||||||
|
<ViewTransitions fallback="none" />
|
||||||
|
|
@ -1,23 +1,30 @@
|
||||||
---
|
---
|
||||||
import Navbar from "@components/Navbar.svelte";
|
import Navbar from "@components/Navbar.svelte";
|
||||||
import RootLayout from "./RootLayout.astro";
|
import HeadContent from "@components/HeadContent.astro";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
noStickyNavbar?: boolean;
|
noStickyNavbar?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title, description, noStickyNavbar } = Astro.props;
|
const { noStickyNavbar } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<RootLayout {title} {description}>
|
<html lang="en">
|
||||||
<Navbar
|
<head>
|
||||||
client:load
|
<slot name="head">
|
||||||
sticky={!noStickyNavbar}
|
<HeadContent />
|
||||||
currentPath={Astro.url.pathname}
|
</slot>
|
||||||
/>
|
</head>
|
||||||
<main class="pb-6">
|
|
||||||
<slot />
|
<body class="overflow-y-scroll bg-gray-50">
|
||||||
</main>
|
<Navbar
|
||||||
</RootLayout>
|
client:load
|
||||||
|
sticky={!noStickyNavbar}
|
||||||
|
currentPath={Astro.url.pathname}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<main class="pb-6">
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
import { ViewTransitions } from "astro:transitions";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
hideScrollbar?: boolean;
|
|
||||||
themeColor?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title, description, hideScrollbar, themeColor } = Astro.props;
|
|
||||||
|
|
||||||
const fullTitle = `${title ? title + " – " : ""}Mikkel Svartveit`;
|
|
||||||
---
|
|
||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>{fullTitle}</title>
|
|
||||||
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width" />
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
content={description ??
|
|
||||||
"Hi, I'm Mikkel! I am a Computer Science student from Norway and this is my playground. Here you will find some programming projects, and a small collection of photos I'm proud of."}
|
|
||||||
/>
|
|
||||||
<meta name="theme-color" content={themeColor ?? "#facc15"} />
|
|
||||||
|
|
||||||
<link rel="icon" href="/favicon.png" />
|
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600&family=Source+Code+Pro&family=Source+Serif+Pro:wght@300;400;600&display=swap"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ViewTransitions fallback="none" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class={`bg-gray-50 ${hideScrollbar ? "" : "overflow-y-scroll"}`}>
|
|
||||||
<slot />
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -4,7 +4,7 @@ import BaseLayout from "../layouts/BaseLayout.astro";
|
||||||
import NotFoundImage from "../assets/images/404.jpeg";
|
import NotFoundImage from "../assets/images/404.jpeg";
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title="Mikkel Svartveit">
|
<BaseLayout>
|
||||||
<section class="mx-auto max-w-4xl px-3 pb-8 pt-12 sm:px-6">
|
<section class="mx-auto max-w-4xl px-3 pb-8 pt-12 sm:px-6">
|
||||||
<h1
|
<h1
|
||||||
class="mb-8 text-center font-serif text-3xl font-light tracking-wide text-gray-600 sm:text-4xl"
|
class="mb-8 text-center font-serif text-3xl font-light tracking-wide text-gray-600 sm:text-4xl"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import type { GetStaticPaths } from "astro";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
import ProseLayout from "@layouts/ProseLayout.astro";
|
import ProseLayout from "@layouts/ProseLayout.astro";
|
||||||
import ArticleViewCounter from "@components/ArticleViewCounter.svelte";
|
import ArticleViewCounter from "@components/ArticleViewCounter.svelte";
|
||||||
|
import HeadContent from "@components/HeadContent.astro";
|
||||||
|
|
||||||
export const getStaticPaths = (async () => {
|
export const getStaticPaths = (async () => {
|
||||||
const blogCollection = await getCollection("blog");
|
const blogCollection = await getCollection("blog");
|
||||||
|
|
@ -19,11 +20,13 @@ export const getStaticPaths = (async () => {
|
||||||
|
|
||||||
const project = Astro.props.entry;
|
const project = Astro.props.entry;
|
||||||
const { Content, headings } = await project.render();
|
const { Content, headings } = await project.render();
|
||||||
const { date, intro } = project.data;
|
const { date, intro, image } = project.data;
|
||||||
const title = headings[0].text;
|
const title = headings[0].text;
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout {title} description={intro}>
|
<BaseLayout>
|
||||||
|
<HeadContent slot="head" {title} description={intro} image={image.src} />
|
||||||
|
|
||||||
<ContainerLayout>
|
<ContainerLayout>
|
||||||
<TextContentLayout>
|
<TextContentLayout>
|
||||||
<p class="mx-auto mb-4 flex items-center text-gray-500">
|
<p class="mx-auto mb-4 flex items-center text-gray-500">
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,14 @@ import ContainerLayout from "@layouts/ContainerLayout.astro";
|
||||||
import BaseLayout from "@layouts/BaseLayout.astro";
|
import BaseLayout from "@layouts/BaseLayout.astro";
|
||||||
import TextContentLayout from "@layouts/TextContentLayout.astro";
|
import TextContentLayout from "@layouts/TextContentLayout.astro";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
import Head from "@components/HeadContent.astro";
|
||||||
|
|
||||||
const articles = await getCollection("blog");
|
const articles = await getCollection("blog");
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title="Articles">
|
<BaseLayout>
|
||||||
|
<Head slot="head" title="Articles" />
|
||||||
|
|
||||||
<ContainerLayout>
|
<ContainerLayout>
|
||||||
<TextContentLayout>
|
<TextContentLayout>
|
||||||
<h1
|
<h1
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import type { GetStaticPaths } from "astro";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import { getFileNameFromPath } from "./index.astro";
|
import { getFileNameFromPath } from "./index.astro";
|
||||||
import RootLayout from "@layouts/RootLayout.astro";
|
import RootLayout from "@layouts/RootLayout.astro";
|
||||||
|
import HeadContent from "@components/HeadContent.astro";
|
||||||
|
|
||||||
export const getStaticPaths = (async () => {
|
export const getStaticPaths = (async () => {
|
||||||
const photos = await Astro.glob("../../assets/photos/*");
|
const photos = await Astro.glob("../../assets/photos/*");
|
||||||
|
|
@ -20,20 +21,24 @@ export const getStaticPaths = (async () => {
|
||||||
const { photo } = Astro.props;
|
const { photo } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<RootLayout title="Photo" hideScrollbar themeColor="#111827">
|
<html lang="en">
|
||||||
<div
|
<head>
|
||||||
class="fixed flex h-[100svh] w-full cursor-pointer justify-center bg-gray-900"
|
<HeadContent title="Photography" />
|
||||||
onclick="
|
</head>
|
||||||
history.back()
|
|
||||||
"
|
<body class="bg-gray-50">
|
||||||
>
|
<div
|
||||||
<Image
|
class="fixed flex h-[100svh] w-full cursor-pointer justify-center bg-gray-900"
|
||||||
src={photo.default}
|
onclick="history.back()"
|
||||||
alt=""
|
>
|
||||||
height={2000}
|
<Image
|
||||||
quality="high"
|
src={photo.default}
|
||||||
class="h-full w-auto rounded object-contain"
|
alt=""
|
||||||
transition:name={photo.default.src}
|
height={2000}
|
||||||
/>
|
quality="high"
|
||||||
</div>
|
class="h-full w-auto rounded object-contain"
|
||||||
</RootLayout>
|
transition:name={photo.default.src}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import ContainerLayout from "@layouts/ContainerLayout.astro";
|
||||||
import BaseLayout from "@layouts/BaseLayout.astro";
|
import BaseLayout from "@layouts/BaseLayout.astro";
|
||||||
import TextContentLayout from "@layouts/TextContentLayout.astro";
|
import TextContentLayout from "@layouts/TextContentLayout.astro";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
|
import HeadContent from "@components/HeadContent.astro";
|
||||||
|
|
||||||
const photos = await Astro.glob("../../assets/photos/*");
|
const photos = await Astro.glob("../../assets/photos/*");
|
||||||
|
|
||||||
|
|
@ -21,7 +22,9 @@ export const getFileNameFromPath = (path: string) => {
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title="Photography" noStickyNavbar>
|
<BaseLayout noStickyNavbar>
|
||||||
|
<HeadContent slot="head" title="Photography" />
|
||||||
|
|
||||||
<ContainerLayout>
|
<ContainerLayout>
|
||||||
<TextContentLayout>
|
<TextContentLayout>
|
||||||
<h1
|
<h1
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import TextContentLayout from "@layouts/TextContentLayout.astro";
|
||||||
import type { GetStaticPaths } from "astro";
|
import type { GetStaticPaths } from "astro";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
import ProseLayout from "@layouts/ProseLayout.astro";
|
import ProseLayout from "@layouts/ProseLayout.astro";
|
||||||
|
import HeadContent from "@components/HeadContent.astro";
|
||||||
|
|
||||||
export const getStaticPaths = (async () => {
|
export const getStaticPaths = (async () => {
|
||||||
const programmingEntries = await getCollection("programming");
|
const programmingEntries = await getCollection("programming");
|
||||||
|
|
@ -18,10 +19,13 @@ export const getStaticPaths = (async () => {
|
||||||
|
|
||||||
const project = Astro.props.entry;
|
const project = Astro.props.entry;
|
||||||
const { Content } = await project.render();
|
const { Content } = await project.render();
|
||||||
const { title, date, technologies, website, repository } = project.data;
|
const { title, description, image, date, technologies, website, repository } =
|
||||||
|
project.data;
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout {title}>
|
<BaseLayout>
|
||||||
|
<HeadContent slot="head" {title} {description} image={image.src} />
|
||||||
|
|
||||||
<ContainerLayout>
|
<ContainerLayout>
|
||||||
<TextContentLayout>
|
<TextContentLayout>
|
||||||
<h1
|
<h1
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,14 @@ import ContainerLayout from "@layouts/ContainerLayout.astro";
|
||||||
import BaseLayout from "@layouts/BaseLayout.astro";
|
import BaseLayout from "@layouts/BaseLayout.astro";
|
||||||
import TextContentLayout from "@layouts/TextContentLayout.astro";
|
import TextContentLayout from "@layouts/TextContentLayout.astro";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
import HeadContent from "@components/HeadContent.astro";
|
||||||
|
|
||||||
const projects = await getCollection("programming");
|
const projects = await getCollection("programming");
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title="Programming">
|
<BaseLayout>
|
||||||
|
<HeadContent slot="head" title="Programming" />
|
||||||
|
|
||||||
<ContainerLayout>
|
<ContainerLayout>
|
||||||
<TextContentLayout>
|
<TextContentLayout>
|
||||||
<h1
|
<h1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue