Hello.

I am Paul Kinlan.

A Developer Advocate for Chrome and the Open Web at Google.

I love the web. The web should allow anyone to access any experience that they need without the need for native install or content walled garden.

How I edit my blogs

Paul Kinlan

A little bit about how I edit my blog: It's Hugo, on Vercel with a custom editor I built.

Read More

User Agents Hitting My Site

Paul Kinlan

Curious about who's visiting my site, I built a user-agent tracker using Vercel middleware and KV storage. It logs every request and displays a live table of user agents and hit counts, refreshing every minute. Check out the code on GitHub!

Read More

Adding ActivityPub to your static site

Paul Kinlan

I added ActivityPub support to my static Hugo blog hosted on Vercel. It now automatically announces new posts to followers on the Fediverse. Key challenges included implementing the ActivityPub protocol for a static site, handling WebFinger discovery, managing Follow/Unfollow requests, and sending signed HTTP requests. I used Vercel Serverless Functions for dynamic request handling and Firebase Firestore for storing follower data. Check out the code and follow me @paul@paul.kinlan.me to see it in action!

Read More

Post Deploy Webhook for Vercel

Paul Kinlan

I needed to find a way to send webhooks after a successful deployment on Vercel, which wasn't a built-in feature. Since Vercel integrations can listen for deployment events, I created one to solve this. It's a simple tool hosted on GitHub that lets you set up custom webhooks for your Vercel projects. It's not on the Vercel Marketplace, and it's more of a workaround until Vercel natively supports deployment webhooks. Check out the GitHub repo for instructions on setting it up with Firebase Firestore.

Read More

Simulating Apache mod_include for Vercel

Paul Kinlan

For my Hugo static site hosted on Vercel, I wanted a simple way to include server-side logic, like a copyright notice, without setting up a full backend. I created a function that mimics Apache's mod_include to inject dynamic content. It rewrites HTML requests through a handler that parses files for <!--#include ... --> directives. The file command injects file content, while the virtual command fetches content from the /api directory (like a modern /cgi-bin/). Caching is crucial for performance. Check out the demo and code. A more robust solution like Cloudflare Workers' HTMLRewriter would be ideal, but this works for simple use cases.

Read More