From 797d93c523b3b1e33fed6c720df40b5e574b7ab7 Mon Sep 17 00:00:00 2001 From: Mikkel Svartveit Date: Mon, 13 May 2024 00:39:58 -0700 Subject: [PATCH] Add view counter to articles --- .gitignore | 3 ++ astro.config.mjs | 8 ++++++ src/actions/index.ts | 18 ++++++++++++ src/components/ArticleViewCounter.svelte | 35 ++++++++++++++++++++++++ src/env.d.ts | 1 + src/pages/articles/[article].astro | 21 ++++++++------ wrangler.toml | 7 +++-- 7 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 src/actions/index.ts create mode 100644 src/components/ArticleViewCounter.svelte diff --git a/.gitignore b/.gitignore index 6d4c0aa..5e13c1d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ pnpm-debug.log* # macOS-specific files .DS_Store + +# Cloudflare +/.wrangler \ No newline at end of file diff --git a/astro.config.mjs b/astro.config.mjs index 4ab7dd5..f9f6ae4 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -13,4 +13,12 @@ export default defineConfig({ enabled: true, }, }), + vite: { + ssr: { + external: ["node:async_hooks"], + }, + }, + experimental: { + actions: true, + }, }); diff --git a/src/actions/index.ts b/src/actions/index.ts new file mode 100644 index 0000000..920b72c --- /dev/null +++ b/src/actions/index.ts @@ -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; + }, + }), +}; diff --git a/src/components/ArticleViewCounter.svelte b/src/components/ArticleViewCounter.svelte new file mode 100644 index 0000000..122f3b2 --- /dev/null +++ b/src/components/ArticleViewCounter.svelte @@ -0,0 +1,35 @@ + + +{#if counter !== null} + + + + + + + + + + + {counter} + +{/if} diff --git a/src/env.d.ts b/src/env.d.ts index acef35f..83f08d1 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -1,2 +1,3 @@ +/// /// /// diff --git a/src/pages/articles/[article].astro b/src/pages/articles/[article].astro index 19683d4..854627e 100644 --- a/src/pages/articles/[article].astro +++ b/src/pages/articles/[article].astro @@ -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; -

- { - new Date(date).toLocaleDateString("en-US", { - month: "long", - day: "numeric", - year: "numeric", - }) - } +

+ + { + new Date(date).toLocaleDateString("en-US", { + month: "long", + day: "numeric", + year: "numeric", + }) + } + + +

diff --git a/wrangler.toml b/wrangler.toml index c44fe1d..6f24bd7 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -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"