[FEAT] SEO best practices

This commit is contained in:
2025-11-26 17:20:09 +01:00
parent accea99408
commit b801cd4c99
9 changed files with 222 additions and 193 deletions

View File

@@ -1,12 +1,12 @@
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import { ref, onMounted } from 'vue';
import { useBlog, type BlogPost } from '../composables/useBlog';
import { useSEO } from '../composables/useSEO';
import { useStructuredData } from '../composables/useStructuredData';
import { RouterLink } from 'vue-router';
const { getPosts } = useBlog();
const { addBlogListSchema, addBreadcrumbSchema } = useStructuredData();
const { addBreadcrumbSchema } = useStructuredData();
const posts = ref<BlogPost[]>([]);
// Set SEO meta tags synchronously
@@ -15,34 +15,18 @@
description: 'Explore our latest articles about sprite sheet generation, game development, pixel art, and sprite animation techniques.',
url: '/blog',
type: 'website',
keywords: 'sprite sheet blog, game development articles, pixel art tutorials, sprite animation'
keywords: 'sprite sheet blog, game development articles, pixel art tutorials, sprite animation',
});
// Add breadcrumb synchronously
addBreadcrumbSchema([
{ name: 'Home', url: '/' },
{ name: 'Blog', url: '/blog' }
{ name: 'Blog', url: '/blog' },
]);
onMounted(async () => {
posts.value = await getPosts();
});
// Watch posts and add structured data when available
watch(posts, (newPosts) => {
if (newPosts.length > 0) {
addBlogListSchema(
newPosts.map(post => ({
title: post.title,
description: post.description,
author: post.author || 'nu11ed',
datePublished: post.date,
image: post.image,
url: `/blog/${post.slug}`
}))
);
}
}, { immediate: true });
</script>
<template>