From 68228c44fcaa57e8b9bf0589508621cae3023b72 Mon Sep 17 00:00:00 2001 From: chronark Date: Mon, 6 Nov 2023 09:39:11 +0100 Subject: [PATCH] fix: og text --- .env.example | 2 +- README.md | 4 +- app/layout.tsx | 117 +++++---- app/projects/[slug]/page.tsx | 48 ++-- app/projects/page.tsx | 236 +++++++++--------- content/projects/envshare.mdx | 2 +- content/projects/qstash.mdx | 4 +- content/projects/upstash-auth-analytics.mdx | 2 +- content/projects/upstash-cli.mdx | 14 +- content/projects/upstash-core-analytics.mdx | 2 +- content/projects/upstash-edge-flags.mdx | 4 +- content/projects/upstash-kafka.mdx | 2 +- .../projects/upstash-ratelimit-analytics.mdx | 4 +- content/projects/upstash-ratelimit.mdx | 4 +- content/projects/upstash-react-ui.mdx | 4 +- content/projects/upstash-redis.mdx | 4 +- content/projects/upstash-web-analytics.mdx | 2 +- package.json | 2 +- pages/api/incr.ts | 72 +++--- 19 files changed, 264 insertions(+), 265 deletions(-) diff --git a/.env.example b/.env.example index d0785c1..2dfe98d 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,2 @@ UPSTASH_REDIS_REST_URL= -UPSTASH_REDIS_REST_TOKEN= \ No newline at end of file +UPSTASH_REDIS_REST_TOKEN= diff --git a/README.md b/README.md index 472dd54..67d854f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

chronark.com

- + My personal website, built with [Next.js](https://nextjs.org/), [Tailwind CSS](https://tailwindcss.com/), [Upstash](https://upstash.com?ref=chronark.com), [Contentlayer](https://www.contentlayer.dev/) and deployed to [Vercel](https://vercel.com/).
@@ -30,4 +30,4 @@ pnpm dev ## Cloning / Forking -Please remove all of my personal information (projects, images, etc.) before deploying your own version of this site. \ No newline at end of file +Please remove all of my personal information (projects, images, etc.) before deploying your own version of this site. diff --git a/app/layout.tsx b/app/layout.tsx index 89b4632..f6582ed 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -5,73 +5,72 @@ import { Metadata } from "next"; import { Analytics } from "./components/analytics"; export const metadata: Metadata = { - title: { - default: "chronark.com", - template: "%s | chronark.com", - }, - description: "Software engineer at upstash.com and founder of planetfall.io", - openGraph: { - title: "chronark.com", - description: - "Software engineer at upstash.com and founder of planetfall.io", - url: "https://chronark.com", - siteName: "chronark.com", - images: [ - { - url: "https://chronark.com/og.png", - width: 1920, - height: 1080, - }, - ], - locale: "en-US", - type: "website", - }, - robots: { - index: true, - follow: true, - googleBot: { - index: true, - follow: true, - "max-video-preview": -1, - "max-image-preview": "large", - "max-snippet": -1, - }, - }, - twitter: { - title: "Chronark", - card: "summary_large_image", - }, - icons: { - shortcut: "/favicon.png", - }, + title: { + default: "chronark.com", + template: "%s | chronark.com", + }, + description: "Co-founder of unkey.dev and founder of planetfall.io", + openGraph: { + title: "chronark.com", + description: + "Co-founder of unkey.dev and founder of planetfall.io", + url: "https://chronark.com", + siteName: "chronark.com", + images: [ + { + url: "https://chronark.com/og.png", + width: 1920, + height: 1080, + }, + ], + locale: "en-US", + type: "website", + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + "max-video-preview": -1, + "max-image-preview": "large", + "max-snippet": -1, + }, + }, + twitter: { + title: "Chronark", + card: "summary_large_image", + }, + icons: { + shortcut: "/favicon.png", + }, }; const inter = Inter({ - subsets: ["latin"], - variable: "--font-inter", + subsets: ["latin"], + variable: "--font-inter", }); const calSans = LocalFont({ - src: "../public/fonts/CalSans-SemiBold.ttf", - variable: "--font-calsans", + src: "../public/fonts/CalSans-SemiBold.ttf", + variable: "--font-calsans", }); export default function RootLayout({ - children, + children, }: { - children: React.ReactNode; + children: React.ReactNode; }) { - return ( - - - - - - {children} - - - ); + return ( + + + + + + {children} + + + ); } diff --git a/app/projects/[slug]/page.tsx b/app/projects/[slug]/page.tsx index ac84624..d3e49bb 100644 --- a/app/projects/[slug]/page.tsx +++ b/app/projects/[slug]/page.tsx @@ -9,40 +9,40 @@ import { Redis } from "@upstash/redis"; export const revalidate = 60; type Props = { - params: { - slug: string; - }; + params: { + slug: string; + }; }; const redis = Redis.fromEnv(); export async function generateStaticParams(): Promise { - return allProjects - .filter((p) => p.published) - .map((p) => ({ - slug: p.slug, - })); + return allProjects + .filter((p) => p.published) + .map((p) => ({ + slug: p.slug, + })); } export default async function PostPage({ params }: Props) { - const slug = params?.slug; - const project = allProjects.find((project) => project.slug === slug); + const slug = params?.slug; + const project = allProjects.find((project) => project.slug === slug); - if (!project) { - notFound(); - } + if (!project) { + notFound(); + } - const views = - (await redis.get(["pageviews", "projects", slug].join(":"))) ?? 0; + const views = + (await redis.get(["pageviews", "projects", slug].join(":"))) ?? 0; - return ( -
-
- + return ( +
+
+ -
- -
-
- ); +
+ +
+
+ ); } diff --git a/app/projects/page.tsx b/app/projects/page.tsx index 57f6a10..90f8138 100644 --- a/app/projects/page.tsx +++ b/app/projects/page.tsx @@ -11,128 +11,128 @@ const redis = Redis.fromEnv(); export const revalidate = 60; export default async function ProjectsPage() { - const views = ( - await redis.mget( - ...allProjects.map((p) => ["pageviews", "projects", p.slug].join(":")), - ) - ).reduce((acc, v, i) => { - acc[allProjects[i].slug] = v ?? 0; - return acc; - }, {} as Record); + const views = ( + await redis.mget( + ...allProjects.map((p) => ["pageviews", "projects", p.slug].join(":")), + ) + ).reduce((acc, v, i) => { + acc[allProjects[i].slug] = v ?? 0; + return acc; + }, {} as Record); - const featured = allProjects.find((project) => project.slug === "unkey")!; - const top2 = allProjects.find((project) => project.slug === "planetfall")!; - const top3 = allProjects.find((project) => project.slug === "highstorm")!; - const sorted = allProjects - .filter((p) => p.published) - .filter( - (project) => - project.slug !== featured.slug && - project.slug !== top2.slug && - project.slug !== top3.slug, - ) - .sort( - (a, b) => - new Date(b.date ?? Number.POSITIVE_INFINITY).getTime() - - new Date(a.date ?? Number.POSITIVE_INFINITY).getTime(), - ); + const featured = allProjects.find((project) => project.slug === "unkey")!; + const top2 = allProjects.find((project) => project.slug === "planetfall")!; + const top3 = allProjects.find((project) => project.slug === "highstorm")!; + const sorted = allProjects + .filter((p) => p.published) + .filter( + (project) => + project.slug !== featured.slug && + project.slug !== top2.slug && + project.slug !== top3.slug, + ) + .sort( + (a, b) => + new Date(b.date ?? Number.POSITIVE_INFINITY).getTime() - + new Date(a.date ?? Number.POSITIVE_INFINITY).getTime(), + ); - return ( -
- -
-
-

- Projects -

-

- Some of the projects are from work and some are on my own time. -

-
-
+ return ( +
+ +
+
+

+ Projects +

+

+ Some of the projects are from work and some are on my own time. +

+
+
-
- - -
-
-
- {featured.date ? ( - - ) : ( - SOON - )} -
- - {" "} - {Intl.NumberFormat("en-US", { notation: "compact" }).format( - views[featured.slug] ?? 0, - )} - -
+
+ + +
+
+
+ {featured.date ? ( + + ) : ( + SOON + )} +
+ + {" "} + {Intl.NumberFormat("en-US", { notation: "compact" }).format( + views[featured.slug] ?? 0, + )} + +
-

- {featured.title} -

-

- {featured.description} -

-
-

- Read more -

-
-
- -
+

+ {featured.title} +

+

+ {featured.description} +

+
+

+ Read more +

+
+
+ +
-
- {[top2, top3].map((project) => ( - -
- - ))} -
-
-
+
+ {[top2, top3].map((project) => ( + +
+ + ))} +
+
+
-
-
- {sorted - .filter((_, i) => i % 3 === 0) - .map((project) => ( - -
- - ))} -
-
- {sorted - .filter((_, i) => i % 3 === 1) - .map((project) => ( - -
- - ))} -
-
- {sorted - .filter((_, i) => i % 3 === 2) - .map((project) => ( - -
- - ))} -
-
-
-
- ); +
+
+ {sorted + .filter((_, i) => i % 3 === 0) + .map((project) => ( + +
+ + ))} +
+
+ {sorted + .filter((_, i) => i % 3 === 1) + .map((project) => ( + +
+ + ))} +
+
+ {sorted + .filter((_, i) => i % 3 === 2) + .map((project) => ( + +
+ + ))} +
+
+
+
+ ); } diff --git a/content/projects/envshare.mdx b/content/projects/envshare.mdx index 59f6253..08fba28 100644 --- a/content/projects/envshare.mdx +++ b/content/projects/envshare.mdx @@ -113,4 +113,4 @@ $ curl -s https://envshare.dev/api/v1/secret/HdPbXgpvUvNk43oxSdK97u "remainingReads": 1 } } -``` \ No newline at end of file +``` diff --git a/content/projects/qstash.mdx b/content/projects/qstash.mdx index 94cffbb..01bc6f0 100644 --- a/content/projects/qstash.mdx +++ b/content/projects/qstash.mdx @@ -4,7 +4,7 @@ description: QStash is a fully managed serverless queue and messaging service de date: "2022-07-18" url: https://upstash.com/qstash published: true - + --- QStash is an HTTP based messaging and scheduling solution for the serverless and edge runtimes. @@ -33,4 +33,4 @@ If you use QStash in the above example, you simply send a request to QStash from With QStash, you can add delays to the requests. Send an email 3 days after the shipment to remind the customer to add a review. You can also schedule tasks. You can send the requests with a CRON expression, so it will be run repetitively. -To learn more about QStash, visit [upstash.com/qstash](upstash.com/qstash). \ No newline at end of file +To learn more about QStash, visit [upstash.com/qstash](upstash.com/qstash). diff --git a/content/projects/upstash-auth-analytics.mdx b/content/projects/upstash-auth-analytics.mdx index 6004cae..94aefb6 100644 --- a/content/projects/upstash-auth-analytics.mdx +++ b/content/projects/upstash-auth-analytics.mdx @@ -5,4 +5,4 @@ url: https://console.upstash.com/ratelimit repository: upstash/auth-analytics --- -TODO: \ No newline at end of file +TODO: diff --git a/content/projects/upstash-cli.mdx b/content/projects/upstash-cli.mdx index 92fc1ae..d21850a 100644 --- a/content/projects/upstash-cli.mdx +++ b/content/projects/upstash-cli.mdx @@ -4,7 +4,7 @@ description: A CLI to provision and manage Upstash resources, including Redis an date: "2022-05-16" repository: upstash/cli published: true - + --- @@ -38,7 +38,7 @@ for windows, linux and mac (both intel and m1). ```bash > upstash - Usage: upstash + Usage: upstash Version: development Description: @@ -47,15 +47,15 @@ for windows, linux and mac (both intel and m1). Options: - -h, --help - Show this help. - -V, --version - Show the version number for this program. + -h, --help - Show this help. + -V, --version - Show the version number for this program. -c, --config - Path to .upstash.json file Commands: - auth - Login and logout - redis - Manage redis database instances - kafka - Manage kafka clusters and topics + auth - Login and logout + redis - Manage redis database instances + kafka - Manage kafka clusters and topics team - Manage your teams and their members Environment variables: diff --git a/content/projects/upstash-core-analytics.mdx b/content/projects/upstash-core-analytics.mdx index d656886..966d891 100644 --- a/content/projects/upstash-core-analytics.mdx +++ b/content/projects/upstash-core-analytics.mdx @@ -5,7 +5,7 @@ date: "2023-02-13" url: https://console.upstash.com/ratelimit repository: upstash/core-analytics published: true - + --- diff --git a/content/projects/upstash-edge-flags.mdx b/content/projects/upstash-edge-flags.mdx index 42c796b..71e4a76 100644 --- a/content/projects/upstash-edge-flags.mdx +++ b/content/projects/upstash-edge-flags.mdx @@ -5,7 +5,7 @@ date: "2022-12-12" url: https://upstash.com/blog/edge-flags-beta repository: upstash/edge-flags published: true - + --- @@ -13,7 +13,7 @@ Whether you want to ship without breaking things, run A/B tests or just want to feature flags are a great way to dynamically change the behaviour of your app without redeploying. We're excited to announce the public beta release of our new feature flagging library: [@upstash/edge-flags](https://github.com/upstash/edge-flags). -*Edge Flags*, as the name implies, is a feature flag solution built to run at the edge. It is using [Upstash Redis](https://upstash.com/), a globally replicated serverless Redis service, to store configuration and is +*Edge Flags*, as the name implies, is a feature flag solution built to run at the edge. It is using [Upstash Redis](https://upstash.com/), a globally replicated serverless Redis service, to store configuration and is designed to work with [Next.js](https://nextjs.org) and [Vercel](https://vercel.com). We want to support other frameworks in the future, so if you have a suggestion, please let us know! With the ability to toggle features on and off at the edge, you can quickly respond diff --git a/content/projects/upstash-kafka.mdx b/content/projects/upstash-kafka.mdx index 9ebb880..36df4b1 100644 --- a/content/projects/upstash-kafka.mdx +++ b/content/projects/upstash-kafka.mdx @@ -5,7 +5,7 @@ date: "2022-01-08" url: https://upstash.com/kafka repository: upstash/upstash-kafka published: true - + --- diff --git a/content/projects/upstash-ratelimit-analytics.mdx b/content/projects/upstash-ratelimit-analytics.mdx index abb412f..ec3e0c9 100644 --- a/content/projects/upstash-ratelimit-analytics.mdx +++ b/content/projects/upstash-ratelimit-analytics.mdx @@ -4,7 +4,7 @@ description: Near realtime analytics for your ratelimits. Integrated into the @u repository: upstash/ratelimit" url: https://console.upstash.com/ratelimit published: true - + --- -TODO: \ No newline at end of file +TODO: diff --git a/content/projects/upstash-ratelimit.mdx b/content/projects/upstash-ratelimit.mdx index 05544ae..7063084 100644 --- a/content/projects/upstash-ratelimit.mdx +++ b/content/projects/upstash-ratelimit.mdx @@ -5,7 +5,7 @@ date: "2022-06-06" url: https://upstash.com/blog/upstash-ratelimit repository: upstash/ratelimit published: true - + --- In today's digital age, serverless computing has become increasingly popular due to its scalability and cost-efficiency. One of the challenges of serverless computing is to manage resources efficiently, and one critical aspect of this is rate limiting. Rate limiting is a technique that limits the number of requests a client can make to a server over a given period. This technique can prevent abuse, improve performance, and reduce costs. One npm package that helps implement rate limiting for serverless applications is @upstash/ratelimit, built on top of Upstash Redis. @@ -46,4 +46,4 @@ const { success } = await ratelimit.limit("identifier") In the code above, we initialize Upstash with our Upstash Redis credentials and define our rate limiting rules. We then call the `limit` function, passing the identifier. The function returns a Promise that resolves with `success` and some other useful data. -`@upstash/ratelimit` is a useful npm package for serverless rate limiting that simplifies the process of implementing rate limiting for serverless applications. The package is built on top of Upstash Redis, which provides a complete solution for serverless applications. With `@upstash/ratelimit`, serverless developers can easily implement rate limiting, which can help prevent abuse, improve performance, and reduce costs. \ No newline at end of file +`@upstash/ratelimit` is a useful npm package for serverless rate limiting that simplifies the process of implementing rate limiting for serverless applications. The package is built on top of Upstash Redis, which provides a complete solution for serverless applications. With `@upstash/ratelimit`, serverless developers can easily implement rate limiting, which can help prevent abuse, improve performance, and reduce costs. diff --git a/content/projects/upstash-react-ui.mdx b/content/projects/upstash-react-ui.mdx index 28f300b..b00e31b 100644 --- a/content/projects/upstash-react-ui.mdx +++ b/content/projects/upstash-react-ui.mdx @@ -5,8 +5,8 @@ date: "2023-02-05" url: https://upstash.com repository: upstash/react-ui published: true - + --- -`@upstash/react-ui` is powering the CLI in your browser on [console.upstash.com](https://console.upstash.com). It allows you to interact with your Upstash Redis database in a simple and intuitive way. \ No newline at end of file +`@upstash/react-ui` is powering the CLI in your browser on [console.upstash.com](https://console.upstash.com). It allows you to interact with your Upstash Redis database in a simple and intuitive way. diff --git a/content/projects/upstash-redis.mdx b/content/projects/upstash-redis.mdx index b373290..95216f6 100644 --- a/content/projects/upstash-redis.mdx +++ b/content/projects/upstash-redis.mdx @@ -5,7 +5,7 @@ date: "2022-03-14" url: https://upstash.com/redis repository: upstash/upstash-redis published: true - + --- Upstash is a cloud-based service provider that offers a Redis-compatible service. In addition to that, we have also created an npm package called `@upstash/redis`. This package provides a strongly typed Redis client that uses HTTP instead of TCP to communicate with the database, making it perfect for serverless and edge runtimes. @@ -42,4 +42,4 @@ console.log(data) await redis.lpush('elements', 'magnesium') data = await redis.lrange('elements', 0, 100 ) console.log(data) -``` \ No newline at end of file +``` diff --git a/content/projects/upstash-web-analytics.mdx b/content/projects/upstash-web-analytics.mdx index 9025b5a..2d450e3 100644 --- a/content/projects/upstash-web-analytics.mdx +++ b/content/projects/upstash-web-analytics.mdx @@ -5,4 +5,4 @@ description: A library to record and analyse web page traffic and user behaviour published: true --- -Coming soon \ No newline at end of file +Coming soon diff --git a/package.json b/package.json index 37067ba..7c3d0f9 100644 --- a/package.json +++ b/package.json @@ -52,4 +52,4 @@ "@opentelemetry/semantic-conventions": "1.13.0" } } -} \ No newline at end of file +} diff --git a/pages/api/incr.ts b/pages/api/incr.ts index 73d519f..79c2ba0 100644 --- a/pages/api/incr.ts +++ b/pages/api/incr.ts @@ -3,45 +3,45 @@ import { NextRequest, NextResponse } from "next/server"; const redis = Redis.fromEnv(); export const config = { - runtime: "edge", + runtime: "edge", }; export default async function incr(req: NextRequest): Promise { - if (req.method !== "POST") { - return new NextResponse("use POST", { status: 405 }); - } - if (req.headers.get("Content-Type") !== "application/json") { - return new NextResponse("must be json", { status: 400 }); - } + if (req.method !== "POST") { + return new NextResponse("use POST", { status: 405 }); + } + if (req.headers.get("Content-Type") !== "application/json") { + return new NextResponse("must be json", { status: 400 }); + } - const body = await req.json(); - let slug: string | undefined = undefined; - if ("slug" in body) { - slug = body.slug; - } - if (!slug) { - return new NextResponse("Slug not found", { status: 400 }); - } - const ip = req.ip; - if (ip) { - // Hash the IP in order to not store it directly in your db. - const buf = await crypto.subtle.digest( - "SHA-256", - new TextEncoder().encode(ip), - ); - const hash = Array.from(new Uint8Array(buf)) - .map((b) => b.toString(16).padStart(2, "0")) - .join(""); + const body = await req.json(); + let slug: string | undefined = undefined; + if ("slug" in body) { + slug = body.slug; + } + if (!slug) { + return new NextResponse("Slug not found", { status: 400 }); + } + const ip = req.ip; + if (ip) { + // Hash the IP in order to not store it directly in your db. + const buf = await crypto.subtle.digest( + "SHA-256", + new TextEncoder().encode(ip), + ); + const hash = Array.from(new Uint8Array(buf)) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); - // deduplicate the ip for each slug - const isNew = await redis.set(["deduplicate", hash, slug].join(":"), true, { - nx: true, - ex: 24 * 60 * 60, - }); - if (!isNew) { - new NextResponse(null, { status: 202 }); - } - } - await redis.incr(["pageviews", "projects", slug].join(":")); - return new NextResponse(null, { status: 202 }); + // deduplicate the ip for each slug + const isNew = await redis.set(["deduplicate", hash, slug].join(":"), true, { + nx: true, + ex: 24 * 60 * 60, + }); + if (!isNew) { + new NextResponse(null, { status: 202 }); + } + } + await redis.incr(["pageviews", "projects", slug].join(":")); + return new NextResponse(null, { status: 202 }); }