mirror of
https://github.com/mikkelsvartveit/astro-personal-website.git
synced 2025-12-22 11:12:38 +00:00
Add view counter to articles
This commit is contained in:
parent
a42cef44bc
commit
797d93c523
7 changed files with 82 additions and 11 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -19,3 +19,6 @@ pnpm-debug.log*
|
|||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
|
||||
# Cloudflare
|
||||
/.wrangler
|
||||
|
|
@ -13,4 +13,12 @@ export default defineConfig({
|
|||
enabled: true,
|
||||
},
|
||||
}),
|
||||
vite: {
|
||||
ssr: {
|
||||
external: ["node:async_hooks"],
|
||||
},
|
||||
},
|
||||
experimental: {
|
||||
actions: true,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
18
src/actions/index.ts
Normal file
18
src/actions/index.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { defineAction, z, getApiContext } from "astro:actions";
|
||||
|
||||
export const server = {
|
||||
registerView: defineAction({
|
||||
input: z.object({ articleSlug: z.string() }),
|
||||
handler: async ({ articleSlug }) => {
|
||||
const context = getApiContext();
|
||||
|
||||
// @ts-ignore
|
||||
const { ViewCountKV } = context.locals.runtime.env;
|
||||
|
||||
let viewCount = (await ViewCountKV.get(articleSlug)) || 0;
|
||||
await ViewCountKV.put(articleSlug, ++viewCount);
|
||||
|
||||
return viewCount;
|
||||
},
|
||||
}),
|
||||
};
|
||||
35
src/components/ArticleViewCounter.svelte
Normal file
35
src/components/ArticleViewCounter.svelte
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<script lang="ts">
|
||||
import { actions } from "astro:actions";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
export let articleSlug: string;
|
||||
|
||||
let counter: number | null = null;
|
||||
|
||||
onMount(async () => {
|
||||
const readCount = await actions.registerView({ articleSlug });
|
||||
|
||||
counter = readCount;
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if counter !== null}
|
||||
<span class="px-2">⋅</span>
|
||||
|
||||
<span class="inline-flex items-center space-x-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" height="12">
|
||||
<!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<style>
|
||||
svg {
|
||||
fill: currentColor;
|
||||
}
|
||||
</style>
|
||||
|
||||
<path
|
||||
d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM144 256a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm144-64c0 35.3-28.7 64-64 64c-7.1 0-13.9-1.2-20.3-3.3c-5.5-1.8-11.9 1.6-11.7 7.4c.3 6.9 1.3 13.8 3.2 20.7c13.7 51.2 66.4 81.6 117.6 67.9s81.6-66.4 67.9-117.6c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3z"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span>{counter}</span>
|
||||
</span>
|
||||
{/if}
|
||||
1
src/env.d.ts
vendored
1
src/env.d.ts
vendored
|
|
@ -1,2 +1,3 @@
|
|||
/// <reference path="../.astro/actions.d.ts" />
|
||||
/// <reference path="../.astro/types.d.ts" />
|
||||
/// <reference types="astro/client" />
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import TextContentLayout from "@layouts/TextContentLayout.astro";
|
|||
import type { GetStaticPaths } from "astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import ProseLayout from "@layouts/ProseLayout.astro";
|
||||
import ArticleViewCounter from "@components/ArticleViewCounter.svelte";
|
||||
|
||||
export const getStaticPaths = (async () => {
|
||||
const blogCollection = await getCollection("blog");
|
||||
|
|
@ -25,14 +26,18 @@ const title = headings[0].text;
|
|||
<BaseLayout {title} description={intro}>
|
||||
<ContainerLayout>
|
||||
<TextContentLayout>
|
||||
<p class="mx-auto mb-4 text-gray-500">
|
||||
{
|
||||
new Date(date).toLocaleDateString("en-US", {
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
})
|
||||
}
|
||||
<p class="mx-auto mb-4 flex items-center text-gray-500">
|
||||
<span>
|
||||
{
|
||||
new Date(date).toLocaleDateString("en-US", {
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
})
|
||||
}
|
||||
</span>
|
||||
|
||||
<ArticleViewCounter articleSlug={project.slug} client:only="svelte" />
|
||||
</p>
|
||||
|
||||
<ProseLayout>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
# Generated by Wrangler on Sun May 12 2024 19:58:01 GMT-0700 (Pacific Daylight Time)
|
||||
name = "astro-personal-website"
|
||||
pages_build_output_dir = "dist"
|
||||
compatibility_date = "2023-10-15"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[env.production]
|
||||
compatibility_date = "2023-10-15"
|
||||
[[kv_namespaces]]
|
||||
binding = "ViewCountKV"
|
||||
id = "682c01c937f94375aeec197e89074c10"
|
||||
|
|
|
|||
Loading…
Reference in a new issue