Merge pull request #157 from bartvdbraak/feat/105-implement-seo-optimizations-merge

Merging of SEO optimizations, sitemap and `robots.txt`
This commit is contained in:
Bart van der Braak 2023-11-18 02:06:21 +01:00 committed by GitHub
commit 5075b3d5ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 144 additions and 100 deletions

View file

@ -29,32 +29,45 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4.1.1
- name: Setup pnpm
uses: pnpm/action-setup@v2.4.0
with:
version: latest
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4.0.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- name: Install dependencies
run: npm install
- name: Retrieve Vercel Preview URL
uses: zentered/vercel-preview-url@v1.1.9
id: vercel_preview_url
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
with:
vercel_project_id: ${{ vars.VERCEL_PROJECT_ID }}
- name: Build production
run: npm run build
- name: Start Preview and Get Preview URL
run: npm run preview -- --port=${{ env.PORT }} & echo $! > preview_pid
- name: Await Vercel Deployment
uses: UnlyEd/github-action-await-vercel@v1.2.43
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
with:
deployment-url: ${{ steps.vercel_preview_url.outputs.preview_url }}
timeout: 120
- name: Install Dependencies
run: npm add -g @unlighthouse/cli puppeteer
run: pnpm install -g @unlighthouse/cli puppeteer
- name: Run Unlighthouse
run: |
unlighthouse-ci \
--site "http://localhost:${{ env.PORT }}" \
--site "${{ steps.vercel_preview_url.outputs.preview_url }}" \
--reporter jsonExpanded \
--build-static
- name: Upload report to Cloudflare pages
uses: cloudflare/wrangler-action@v3.3.2
uses: cloudflare/wrangler-action@2.0.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
command: pages deploy .unlighthouse --project-name="${{ env.CLOUDFLARE_PROJECT }}" --branch=${{ env.CLOUDFLARE_BRANCH }}

View file

@ -8,7 +8,7 @@
<link rel="icon" type="image/png" sizes="32x32" href="%sveltekit.assets%/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="%sveltekit.assets%/favicon-16x16.png" />
<link rel="manifest" href="%sveltekit.assets%/site.webmanifest" />
<link rel="mask-icon" href="%sveltekit.assets%/safari-pinned-tab.svg" color="#5bbad5" />
<link rel="mask-icon" href="%sveltekit.assets%/safari-pinned-tab.svg" color="#000000" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<title></title>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -20,7 +20,7 @@
<AppBar background="">
<svelte:fragment slot="lead">
<a href="/" class="md:ml-4 ml-1">
<img src="./logo@3x.png" alt="hellob.art logo" class="max-h-8" />
<img width="212" height="32" src="./logo@3x.png" alt="hellob.art logo" />
</a>
</svelte:fragment>

4
src/lib/site-config.ts Normal file
View file

@ -0,0 +1,4 @@
export const SITE_URL = 'https://hellob.art';
export const SITE_TITLE = 'hellob.art';
export const SITE_DESCRIPTION = '';
export const DEFAULT_OG_IMAGE = '';

View file

@ -5,6 +5,11 @@
import Footer from '../lib/components/Footer.svelte';
import Navigation from '../lib/components/Navigation.svelte';
import Header from '$lib/components/Header.svelte';
import { fade } from 'svelte/transition';
export let data;
$: ({ pathname } = data);
import { dev } from '$app/environment';
import { inject } from '@vercel/analytics';
@ -47,7 +52,11 @@
<Header {progress} />
</svelte:fragment>
<slot />
{#key pathname}
<div in:fade={{ duration: 300, delay: 400 }} out:fade={{ duration: 300 }}>
<slot />
</div>
{/key}
<svelte:fragment slot="pageFooter">
<Footer />

7
src/routes/+layout.ts Normal file
View file

@ -0,0 +1,7 @@
export const load = ({ url }) => {
const { pathname } = url;
return {
pathname
};
};

View file

@ -21,7 +21,6 @@
<div class="h-64 overflow-hidden rounded-lg bg-gray-100 shadow-lg md:h-auto sticky top-10">
<img
src={bartvdbraakImage}
loading="lazy"
alt="Bart van der Braak with a noire effect"
class="h-full w-full object-cover profile-fit"
/>

View file

@ -31,9 +31,8 @@ const projects: Project[] = [
headerImage: keyweaveImage,
headerSubTitle: 'Open Source Project',
title: 'Keyweave',
description: `Keyweave is an open-source tool crafted to seamlessly fetch secrets from Azure Key Vault
and weave them into a convenient .env file. Developed in Rust, Keyweave stands out for its efficiency
and user-friendly design, making it an ideal choice for managing your application's secrets.`,
description: `Keyweave is an open-source tool crafted in Rust to seamlessly fetch secrets from Azure Key Vault
and weave them into a convenient .env file.`,
logo: keyweaveLogo,
contributors: [],
date: '11-05-2023'

View file

@ -0,0 +1,41 @@
import { SITE_URL } from '$lib/site-config';
/** @type {import('@sveltejs/kit').RequestHandler} */
export async function GET() {
const pages = ['projects', 'toolbox'];
const body = sitemap(pages);
return new Response(body, {
headers: {
'Cache-Control': `public, max-age=${86400}`, // 24 hours
'Content-Type': 'application/xml'
}
});
}
const sitemap = (pages: string[]) => `<?xml version="1.0" encoding="UTF-8" ?>
<urlset
xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="https://www.google.com/schemas/sitemap-news/0.9"
xmlns:xhtml="https://www.w3.org/1999/xhtml"
xmlns:mobile="https://www.google.com/schemas/sitemap-mobile/1.0"
xmlns:image="https://www.google.com/schemas/sitemap-image/1.1"
xmlns:video="https://www.google.com/schemas/sitemap-video/1.1"
>
<url>
<loc>${SITE_URL}</loc>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
${pages
.map(
(page) => `
<url>
<loc>${SITE_URL}/${page}</loc>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
`
)
.join('')}
</urlset>`;

View file

@ -1,20 +0,0 @@
<script lang="ts">
import { Canvas } from '@threlte/core';
import Scene from '../toolbox/Scene.svelte';
import { Theatre } from '@threlte/theatre';
import { T } from '@threlte/core';
</script>
<svelte:head>
<title>hellob.art &mdash; theatre</title>
</svelte:head>
<main class="container h-screen w-full">
<Canvas>
<Theatre>
<Scene />
<T.AxesHelper />
<T.GridHelper />
</Theatre>
</Canvas>
</main>

View file

@ -1,21 +0,0 @@
<script>
import { T, useFrame } from '@threlte/core';
import { OrbitControls } from '@threlte/extras';
import Warp from '../toolbox/models/Warp.svelte';
let githubRotation = 0;
useFrame((state, delta) => {
githubRotation += 0.1 * delta;
});
</script>
<T.PerspectiveCamera position={[0, 5, 10]} makeDefault>
<OrbitControls target.y={1.5} />
</T.PerspectiveCamera>
<T.DirectionalLight intensity={0.5} position.x={2} position.y={3} />
<T.AmbientLight intensity={0.9} />
<Warp rotation.y={githubRotation} />
<T.AxesHelper></T.AxesHelper>
<T.GridHelper></T.GridHelper>

View file

@ -27,7 +27,7 @@
</p>
</div>
<div class="md:col-span-1 flex justify-end">
<div class="h-60 w-full">
<div class="h-60 md:h-full w-full">
<Canvas>
<Scene />
</Canvas>
@ -35,15 +35,17 @@
</div>
</div>
<div class="columns-1 md:columns-2 lg:columns-3 gap-6 w-full mb-12">
<ul class="columns-1 md:columns-2 lg:columns-3 gap-6 w-full mb-12">
{#each tools as tool}
<ToolCard
name={tool.name}
title={tool.title}
description={tool.description}
logo={tool.logo}
toolUrl={tool.toolUrl}
/>
<li>
<ToolCard
name={tool.name}
title={tool.title}
description={tool.description}
logo={tool.logo}
toolUrl={tool.toolUrl}
/>
</li>
{/each}
</div>
</ul>
</div>

View file

@ -14,7 +14,12 @@
>
<div class="flex flex-col gap-6">
<div class="flex gap-6">
<img src={logo} alt={name + ' logo'} class="h-12 w-12 rounded-sm object-contain" />
<img
src={logo}
alt={name + ' logo'}
class="h-12 w-12 rounded-sm object-contain"
loading="lazy"
/>
<div class="grow">
<h4 class="mb-0">{name}</h4>
<p class="text-faded text-sm font-normal">{title}</p>

6
static/robots.txt Normal file
View file

@ -0,0 +1,6 @@
Sitemap: https://hellob.art/sitemap.xml
# https://developers.google.com/search/docs/advanced/sitemaps/build-sitemap#addsitemap
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View file

@ -2,24 +2,24 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M0 2560 l0 -2560 2560 0 2560 0 0 2560 0 2560 -2560 0 -2560 0 0
-2560z m4610 0 l0 -2050 -2050 0 -2050 0 0 2050 0 2050 2050 0 2050 0 0 -2050z"/>
<path d="M2820 4080 c0 -242 2 -270 16 -270 30 0 222 -69 296 -106 113 -57
214 -129 311 -223 196 -189 315 -403 373 -671 26 -119 26 -381 0 -500 -85
-393 -326 -710 -672 -887 -90 -46 -273 -113 -309 -113 -13 0 -15 -38 -15 -270
l0 -270 765 0 765 0 0 1790 0 1790 -765 0 -765 0 0 -270z"/>
<path d="M2382 3569 c-90 -16 -238 -69 -318 -115 -244 -139 -406 -343 -491
-621 -25 -82 -27 -100 -27 -273 0 -173 2 -191 27 -273 58 -187 145 -334 274
-458 131 -126 259 -201 438 -256 84 -25 102 -27 275 -27 173 0 191 2 275 27
355 108 602 355 712 713 25 83 27 101 27 274 0 173 -2 191 -27 273 -58 187
-135 317 -266 448 -132 132 -264 210 -448 265 -75 22 -111 27 -243 30 -85 1
-179 -1 -208 -7z"/>
<path d="M0 3500 l0 -3500 1575 0 1575 0 0 350 0 350 -1225 0 -1225 0 0 2800
0 2800 1225 0 1225 0 0 350 0 350 -1575 0 -1575 0 0 -3500z"/>
<path d="M3850 6475 l0 -175 1225 0 1225 0 0 -2800 0 -2800 -1225 0 -1225 0 0
-175 0 -175 1400 0 1400 0 0 3150 0 3150 -1400 0 -1400 0 0 -175z"/>
<path d="M3850 5581 l0 -368 40 -7 c147 -23 466 -166 622 -278 516 -373 793
-984 728 -1606 -56 -532 -349 -1008 -798 -1297 -146 -94 -426 -211 -552 -231
l-40 -7 0 -368 0 -369 1050 0 1050 0 0 2450 0 2450 -1050 0 -1050 0 0 -369z"/>
<path d="M3322 4889 c-175 -24 -368 -89 -517 -176 -121 -69 -212 -142 -317
-252 -187 -194 -301 -410 -360 -684 -31 -145 -31 -407 0 -554 63 -294 193
-527 409 -733 200 -192 431 -311 708 -366 134 -27 396 -25 532 4 294 63 526
193 734 409 187 195 302 415 361 686 31 146 31 408 0 554 -64 294 -193 526
-410 734 -194 187 -415 303 -680 359 -114 24 -350 34 -460 19z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,19 +1,19 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
"name": "",
"short_name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}