Skip to content

Commit

Permalink
Use next/after to increment views
Browse files Browse the repository at this point in the history
  • Loading branch information
akhila-ariyachandra committed Oct 17, 2024
1 parent cd983bc commit 0ab4f7a
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 117 deletions.
76 changes: 76 additions & 0 deletions app/_components/views.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { db } from "@/_db/connection";
import { post } from "@/_db/schema";
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
import { eq } from "drizzle-orm";
import { headers } from "next/headers";
import { unstable_after as after } from "next/server";
import { Suspense } from "react";

type ViewsProps = {
slug: string;
increment?: boolean;
};

const Views = ({ slug, increment = false }: ViewsProps) => {
return (
<Suspense fallback={<span className="invisible">0 views</span>}>
<ViewsBase slug={slug} increment={increment} />
</Suspense>
);
};

export default Views;

const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(1, "60 s"),
analytics: true,
});

const ViewsBase = async ({ slug, increment }: ViewsProps) => {
const headersStore = await headers();

const results = await db.select().from(post).where(eq(post.slug, slug));
const views = results[0]?.views ?? 0;

if (increment) {
after(async () => {
let ip = "";

const FALLBACK_IP_ADDRESS = "0.0.0.0";
const forwardedFor = headersStore.get("x-forwarded-for");

if (forwardedFor) {
ip = forwardedFor.split(",")[0] ?? FALLBACK_IP_ADDRESS;
} else {
ip = headersStore.get("x-real-ip") ?? FALLBACK_IP_ADDRESS;
}

const { success } = await ratelimit.limit(`${ip}-${slug}`);

if (!success) {
return false;
}

// Check if row exists
const results = await db.select().from(post).where(eq(post.slug, slug));
const result = results[0];
if (!result) {
// Create the record
await db.insert(post).values({
slug,
views: 1,
});
} else {
// Update the record
await db
.update(post)
.set({ views: result.views + 1 })
.where(eq(post.slug, slug));
}
});
}

return <span>{views} views</span>;
};
57 changes: 0 additions & 57 deletions app/_components/views/actions.ts

This file was deleted.

1 change: 0 additions & 1 deletion app/_components/views/index.ts

This file was deleted.

24 changes: 0 additions & 24 deletions app/_components/views/views-incrementer.tsx

This file was deleted.

31 changes: 0 additions & 31 deletions app/_components/views/views.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const BlogPostPage = async (props: BlogPostPageProps) => {
{" - "}
</span>

<Views slug={post._meta.path} incrementOnMount />
<Views slug={post._meta.path} increment />
</div>

<MDXComponent mdx={post.mdx} />
Expand Down
5 changes: 2 additions & 3 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ const withBundleAnalyzer = bundleAnalyzer({
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
after: true,
reactCompiler: true,
ppr: true,
dynamicIO: true,
},
reactStrictMode: true,
images: {
Expand Down Expand Up @@ -41,4 +40,4 @@ const nextConfig = {
},
};

export default withBundleAnalyzer(withContentCollections(nextConfig));
export default withContentCollections(withBundleAnalyzer(nextConfig));

0 comments on commit 0ab4f7a

Please sign in to comment.