mirror of
https://github.com/timmypidashev/web.git
synced 2026-04-14 11:03:50 +00:00
Update blog metrics; add vercel imsights
This commit is contained in:
@@ -5,6 +5,7 @@ import ContentLayout from "@/layouts/content.astro";
|
||||
import { getArticleSchema } from "@/lib/structuredData";
|
||||
import { blogWebsite } from "@/lib/structuredData";
|
||||
import { Comments } from "@/components/blog/comments";
|
||||
import { incrementViews, getViews } from "@/lib/views";
|
||||
|
||||
// This is a dynamic route in SSR mode
|
||||
const { slug } = Astro.params;
|
||||
@@ -20,6 +21,14 @@ if (!post || (!import.meta.env.DEV && post.data.isDraft === true)) {
|
||||
});
|
||||
}
|
||||
|
||||
// Track page view and get count
|
||||
let views = 0;
|
||||
if (!import.meta.env.DEV) {
|
||||
views = await incrementViews(post.id);
|
||||
} else {
|
||||
views = await getViews(post.id);
|
||||
}
|
||||
|
||||
// Dynamically render the content
|
||||
const { Content } = await render(post);
|
||||
|
||||
@@ -84,12 +93,18 @@ const jsonLd = {
|
||||
<time dateTime={post.data.date instanceof Date ? post.data.date.toISOString() : post.data.date} class="text-blue">
|
||||
{formattedDate}
|
||||
</time>
|
||||
{views > 0 && (
|
||||
<>
|
||||
<span class="text-foreground/50">•</span>
|
||||
<span class="text-green">{views.toLocaleString()} view{views !== 1 ? "s" : ""}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2 mt-2">
|
||||
{post.data.tags.map((tag) => (
|
||||
<span
|
||||
class="text-xs md:text-base text-aqua hover:text-aqua-bright transition-colors duration-200"
|
||||
onclick={`window.location.href='/blog/tag/${tag}'`}
|
||||
onclick={`window.location.href='/blog/tags/${encodeURIComponent(tag)}'`}
|
||||
>
|
||||
#{tag}
|
||||
</span>
|
||||
|
||||
32
src/pages/blog/popular/index.astro
Normal file
32
src/pages/blog/popular/index.astro
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import ContentLayout from "@/layouts/content.astro";
|
||||
import { BlogHeader } from "@/components/blog/header";
|
||||
import { BlogPostList } from "@/components/blog/post-list";
|
||||
import { getAllViews } from "@/lib/views";
|
||||
|
||||
const posts = (await getCollection("blog", ({ data }) => {
|
||||
return import.meta.env.DEV || data.isDraft !== true;
|
||||
})).map(post => ({
|
||||
...post,
|
||||
data: {
|
||||
...post.data,
|
||||
date: post.data.date.toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric"
|
||||
})
|
||||
}
|
||||
}));
|
||||
|
||||
// Get view counts and sort by popularity
|
||||
const views = await getAllViews(posts.map(p => p.id));
|
||||
const sorted = [...posts].sort((a, b) => (views[b.id] || 0) - (views[a.id] || 0));
|
||||
---
|
||||
<ContentLayout
|
||||
title="Most Popular | Blog | Timothy Pidashev"
|
||||
description="Most popular blog posts by view count."
|
||||
>
|
||||
<BlogHeader client:load />
|
||||
<BlogPostList posts={sorted} client:load />
|
||||
</ContentLayout>
|
||||
38
src/pages/blog/tags/[...slug].astro
Normal file
38
src/pages/blog/tags/[...slug].astro
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import ContentLayout from "@/layouts/content.astro";
|
||||
import TaggedPosts from "@/components/blog/tagged-posts";
|
||||
|
||||
const { slug } = Astro.params;
|
||||
const tag = decodeURIComponent(slug || "");
|
||||
|
||||
if (!tag) {
|
||||
return Astro.redirect("/blog/tags");
|
||||
}
|
||||
|
||||
const filteredPosts = (await getCollection("blog", ({ data }) => {
|
||||
return (import.meta.env.DEV || data.isDraft !== true) && data.tags.includes(tag);
|
||||
})).sort((a, b) => {
|
||||
return b.data.date.valueOf() - a.data.date.valueOf();
|
||||
}).map(post => ({
|
||||
...post,
|
||||
data: {
|
||||
...post.data,
|
||||
date: post.data.date.toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric"
|
||||
})
|
||||
}
|
||||
}));
|
||||
|
||||
if (filteredPosts.length === 0) {
|
||||
return Astro.redirect("/blog/tags");
|
||||
}
|
||||
---
|
||||
<ContentLayout
|
||||
title={`#${tag} | Blog | Timothy Pidashev`}
|
||||
description={`Blog posts tagged with "${tag}".`}
|
||||
>
|
||||
<TaggedPosts tag={tag} posts={filteredPosts} client:load />
|
||||
</ContentLayout>
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import ContentLayout from "@/layouts/content.astro";
|
||||
|
||||
import { BlogHeader } from "@/components/blog/header";
|
||||
import TagList from "@/components/blog/tag-list";
|
||||
|
||||
const posts = (await getCollection("blog", ({ data }) => {
|
||||
@@ -20,9 +20,10 @@ const posts = (await getCollection("blog", ({ data }) => {
|
||||
}
|
||||
}));
|
||||
---
|
||||
<ContentLayout
|
||||
title="Blog | Timothy Pidashev"
|
||||
description="My experiences and technical insights into software development and the ever-evolving world of programming."
|
||||
<ContentLayout
|
||||
title="Browse Tags | Blog | Timothy Pidashev"
|
||||
description="Browse blog posts by tag."
|
||||
>
|
||||
<TagList posts={posts} />
|
||||
<BlogHeader client:load />
|
||||
<TagList posts={posts} client:load />
|
||||
</ContentLayout>
|
||||
|
||||
Reference in New Issue
Block a user