Remove custom analytics in favor of Vercel defaults

The changes remove custom analytics tracking in favor of using Vercel's
default page view tracking functionality.
This commit is contained in:
2025-08-27 13:25:21 +02:00
parent 9bac3cf33c
commit 30805b7bb9
3 changed files with 9 additions and 221 deletions

View File

@@ -1,6 +1,4 @@
import { NextRequest, NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
import { track } from "@vercel/analytics/server";
import { parseBibtex } from "~/lib/bibtex";
import { readFile } from "fs/promises"; import { readFile } from "fs/promises";
import { join } from "path"; import { join } from "path";
@@ -16,47 +14,7 @@ export async function GET(
} }
try { try {
// Read the BibTeX file to get publication metadata // Serve the PDF file directly - Vercel Analytics will automatically track the route access
const bibtexPath = join(process.cwd(), "public", "publications.bib");
const bibtexContent = await readFile(bibtexPath, "utf-8");
const publications = parseBibtex(bibtexContent);
// Find the publication that matches this PDF
const publication = publications.find(
(pub) =>
pub.paperUrl?.includes(filename) ||
pub.posterUrl?.includes(filename) ||
pub.slidesUrl?.includes(filename),
);
// Track the PDF access
if (publication) {
const isPoster = publication.posterUrl?.includes(filename);
const isSlides = publication.slidesUrl?.includes(filename);
let fileType = "paper";
if (isPoster) fileType = "poster";
if (isSlides) fileType = "slides";
await track("Publication PDF Access", {
title: publication.title,
type: publication.type,
year: publication.year.toString(),
pdf_type: fileType,
citation_key: publication.citationKey || "",
venue: publication.venue || "",
access_method: "direct_url",
filename: filename,
});
} else {
// Track unknown PDF access
await track("Unknown PDF Access", {
filename: filename,
access_method: "direct_url",
});
}
// Serve the PDF file
const pdfPath = join(process.cwd(), "public", "publications", filename); const pdfPath = join(process.cwd(), "public", "publications", filename);
const pdfBuffer = await readFile(pdfPath); const pdfBuffer = await readFile(pdfPath);
@@ -69,13 +27,6 @@ export async function GET(
}); });
} catch (error) { } catch (error) {
console.error("Error serving PDF:", error); console.error("Error serving PDF:", error);
// Track the error
await track("PDF Access Error", {
filename: filename,
error: error instanceof Error ? error.message : "Unknown error",
});
return new NextResponse("PDF not found", { status: 404 }); return new NextResponse("PDF not found", { status: 404 });
} }
} }

View File

@@ -22,12 +22,7 @@ import { Skeleton } from "~/components/ui/skeleton";
import { CardSkeleton } from "~/components/ui/skeletons"; import { CardSkeleton } from "~/components/ui/skeletons";
import type { Publication } from "~/lib/bibtex"; import type { Publication } from "~/lib/bibtex";
import { parseBibtex } from "~/lib/bibtex"; import { parseBibtex } from "~/lib/bibtex";
import { // No custom tracking needed - Vercel automatically tracks page views
trackPdfView,
trackDoiClick,
trackBibtexDownload,
trackSlidesView,
} from "~/lib/analytics";
export default function PublicationsPage() { export default function PublicationsPage() {
const [publications, setPublications] = useState<Publication[]>([]); const [publications, setPublications] = useState<Publication[]>([]);
@@ -45,15 +40,6 @@ export default function PublicationsPage() {
}, []); }, []);
const downloadBibtex = (pub: Publication) => { const downloadBibtex = (pub: Publication) => {
// Track the BibTeX download
trackBibtexDownload({
publicationTitle: pub.title,
publicationType: pub.type,
publicationYear: pub.year,
citationKey: pub.citationKey,
venue: pub.venue,
});
const { const {
title, title,
authors, authors,
@@ -95,50 +81,7 @@ export default function PublicationsPage() {
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
}; };
const handlePaperClick = (pub: Publication) => { // No custom click handlers needed - Vercel automatically tracks API route access
trackPdfView({
publicationTitle: pub.title,
publicationType: pub.type,
publicationYear: pub.year,
citationKey: pub.citationKey,
venue: pub.venue,
pdfType: "paper",
});
};
const handlePosterClick = (pub: Publication) => {
trackPdfView({
publicationTitle: pub.title,
publicationType: pub.type,
publicationYear: pub.year,
citationKey: pub.citationKey,
venue: pub.venue,
pdfType: "poster",
});
};
const handleDoiClick = (pub: Publication) => {
if (pub.doi) {
trackDoiClick({
publicationTitle: pub.title,
publicationType: pub.type,
publicationYear: pub.year,
citationKey: pub.citationKey,
venue: pub.venue,
doi: pub.doi,
});
}
};
const handleSlidesClick = (pub: Publication) => {
trackSlidesView({
publicationTitle: pub.title,
publicationType: pub.type,
publicationYear: pub.year,
citationKey: pub.citationKey,
venue: pub.venue,
});
};
return ( return (
<div className="space-y-6"> <div className="space-y-6">
@@ -179,7 +122,6 @@ export default function PublicationsPage() {
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-muted-foreground hover:text-primary sm:flex-shrink-0" className="text-muted-foreground hover:text-primary sm:flex-shrink-0"
onClick={() => handlePaperClick(pub)}
> >
<ArrowUpRight className="h-5 w-5" /> <ArrowUpRight className="h-5 w-5" />
</Link> </Link>
@@ -222,7 +164,6 @@ export default function PublicationsPage() {
href={`https://doi.org/${pub.doi}`} href={`https://doi.org/${pub.doi}`}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
onClick={() => handleDoiClick(pub)}
> >
<Badge <Badge
variant="secondary" variant="secondary"
@@ -238,7 +179,6 @@ export default function PublicationsPage() {
href={pub.paperUrl} href={pub.paperUrl}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
onClick={() => handlePaperClick(pub)}
> >
<Badge <Badge
variant="secondary" variant="secondary"
@@ -254,7 +194,6 @@ export default function PublicationsPage() {
href={pub.posterUrl} href={pub.posterUrl}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
onClick={() => handlePosterClick(pub)}
> >
<Badge <Badge
variant="secondary" variant="secondary"
@@ -270,7 +209,6 @@ export default function PublicationsPage() {
href={pub.slidesUrl} href={pub.slidesUrl}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
onClick={() => handleSlidesClick(pub)}
> >
<Badge <Badge
variant="secondary" variant="secondary"

View File

@@ -1,111 +1,10 @@
import { track } from "@vercel/analytics";
/** /**
* Analytics tracking utilities for publication interactions * Analytics utilities for publication interactions
* *
* This module provides tracking functions for various publication-related actions * Since we're using Vercel's free plan, we rely on automatic page view tracking
* using Vercel Analytics. It tracks paper downloads, DOI clicks, BibTeX downloads, * rather than custom events. The PDF proxy routes will show up in analytics
* and other publication interactions with detailed metadata. * as page views for /api/publications/[filename] routes.
*
* @example
* ```typescript
* import { trackPdfView } from '~/lib/analytics';
*
* // Track when a user clicks on a paper PDF link
* trackPdfView({
* publicationTitle: "My Research Paper",
* publicationType: "conference",
* publicationYear: 2024,
* citationKey: "Author2024",
* venue: "IEEE Conference",
* pdfType: "paper"
* });
* ```
*/ */
export interface PublicationTrackingData { // No custom tracking functions needed - Vercel automatically tracks all page views
publicationTitle: string; // including API route access at /api/publications/[filename]
publicationType: "conference" | "journal" | "workshop" | "thesis";
publicationYear: number;
linkType: "paper" | "poster" | "slides" | "doi" | "bibtex";
citationKey?: string;
venue?: string;
}
/**
* Track publication link clicks with detailed metadata
*/
export function trackPublicationLink(data: PublicationTrackingData) {
track("Publication Link Click", {
title: data.publicationTitle,
type: data.publicationType,
year: data.publicationYear.toString(),
link_type: data.linkType,
citation_key: data.citationKey || "",
venue: data.venue || "",
});
}
/**
* Track BibTeX downloads specifically
*/
export function trackBibtexDownload(
data: Omit<PublicationTrackingData, "linkType">,
) {
track("BibTeX Download", {
title: data.publicationTitle,
type: data.publicationType,
year: data.publicationYear.toString(),
citation_key: data.citationKey || "",
venue: data.venue || "",
});
}
/**
* Track PDF views (paper or poster)
*/
export function trackPdfView(
data: Omit<PublicationTrackingData, "linkType"> & {
pdfType: "paper" | "poster";
},
) {
track("Publication PDF Click", {
title: data.publicationTitle,
type: data.publicationType,
year: data.publicationYear.toString(),
pdf_type: data.pdfType,
citation_key: data.citationKey || "",
venue: data.venue || "",
});
}
/**
* Track DOI clicks
*/
export function trackDoiClick(
data: Omit<PublicationTrackingData, "linkType"> & { doi: string },
) {
track("DOI Link Click", {
title: data.publicationTitle,
type: data.publicationType,
year: data.publicationYear.toString(),
doi: data.doi,
citation_key: data.citationKey || "",
venue: data.venue || "",
});
}
/**
* Track slides clicks - user intent/engagement
*/
export function trackSlidesView(
data: Omit<PublicationTrackingData, "linkType">,
) {
track("Publication Slides Click", {
title: data.publicationTitle,
type: data.publicationType,
year: data.publicationYear.toString(),
citation_key: data.citationKey || "",
venue: data.venue || "",
});
}