Vercel Integration
Connect your Vercel-hosted website to Blogree for automatic deployments. Whenever you publish, update, or delete a post in Blogree, your Vercel site will automatically rebuild and deploy the changes instantly.
Estimated setup time: 10 minutes
How It Works
Here's the flow when you publish a post in Blogree:
- You publish a post in Blogree Dashboard
- Blogree sends a webhook signal to your Vercel function
- Your Vercel function verifies the request is really from Blogree
- Your Vercel function triggers a deployment hook
- Vercel rebuilds your site with the new content
- Your website is live with the new post! ✅
Step 1: Create the Webhook Receiver Function
First, we need to create a Serverless Function in Vercel that receives webhooks from Blogree. This function will trigger your site to rebuild whenever content changes.
In the root of your project, create a folder named api (if you don't have one) and add a file named blogree.js.
/**
* api/blogree.js
* This Serverless Function receives Blogree webhooks and triggers Vercel rebuilds
*/
const crypto = require('crypto');
const https = require('https');
const http = require('http');
const WEBHOOK_SECRET = process.env.BLOGREE_WEBHOOK_SECRET;
const BUILD_HOOK_URL = process.env.BLOGREE_BUILD_HOOK_URL;
// Verify the webhook signature from Blogree
function verifySignature(rawBody, header) {
if (!WEBHOOK_SECRET) {
console.log('[Blogree] Warning: BLOGREE_WEBHOOK_SECRET not set');
return true;
}
if (!header) {
console.log('[Blogree] Error: Missing X-Blogree-Signature header');
return false;
}
const expected = 'sha256=' + crypto.createHmac('sha256', WEBHOOK_SECRET).update(rawBody).digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
} catch (err) {
console.log('[Blogree] Signature verification failed:', err.message);
return false;
}
}
// Trigger a Vercel deployment
function triggerBuild(postSlug) {
return new Promise((resolve, reject) => {
if (!BUILD_HOOK_URL) {
console.log('[Blogree] Warning: BLOGREE_BUILD_HOOK_URL not set');
return resolve();
}
console.log(`[Blogree] Triggering rebuild for post: ${postSlug}`);
const url = new URL(BUILD_HOOK_URL);
const req = (url.protocol === 'https:' ? https : http).request(
{
hostname: url.hostname,
path: url.pathname + url.search,
method: 'POST',
headers: { 'Content-Length': 0 }
},
(res) => {
console.log(`[Blogree] Vercel rebuild triggered — Status: ${res.statusCode}`);
resolve();
}
);
req.on('error', (err) => {
console.log('[Blogree] Error triggering rebuild:', err.message);
reject(err);
});
req.end();
});
}
// Get raw body for signature verification
function rawBody(req) {
return new Promise((resolve, reject) => {
let data = '';
req.on('data', (chunk) => (data += chunk));
req.on('end', () => resolve(data));
req.on('error', reject);
});
}
// Main handler
module.exports = async (req, res) => {
// Only accept POST requests
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
// Get the raw body for signature verification
const body = await rawBody(req);
const signature = req.headers['x-blogree-signature'] || '';
// Verify the request is really from Blogree
if (!verifySignature(body, signature)) {
console.log('[Blogree] Invalid signature - rejecting request');
return res.status(401).json({ error: 'Invalid signature' });
}
// Parse the webhook payload
let payload;
try {
payload = JSON.parse(body);
} catch (err) {
console.log('[Blogree] Invalid JSON payload');
return res.status(400).json({ error: 'Invalid JSON' });
}
// Extract post information
const postSlug = payload.post?.slug || 'unknown';
const event = payload.event || 'unknown';
console.log(`[Blogree] Received event: ${event} for post: ${postSlug}`);
// Trigger the Vercel rebuild
await triggerBuild(postSlug);
return res.status(200).json({ success: true, message: 'Rebuild triggered' });
} catch (err) {
const errorMessage = err instanceof Error ? err.message : String(err);
console.log('[Blogree] Error processing webhook:', errorMessage);
return res.status(500).json({ error: errorMessage });
}
};Step 2: Create Your Vercel Configuration
Create a vercel.json file in your project root to configure your Serverless Function.
{
"functions": {
"api/blogree.js": {
"memory": 128
}
}
}Step 3: Create a Vercel Deploy Hook
Now we need to create a Deploy Hook in Vercel that your function can trigger to rebuild your site.
- Go to your Vercel Dashboard and select your project
- Navigate to Settings → Git → Deploy Hooks
- Click Create Hook
- Name it Blogree
- Select your main branch (usually
mainormaster) - Click Create Hook
- Copy the generated URL (it will look like
https://api.vercel.com/v1/integrations/deploy/abc...)
Step 4: Add Environment Variables to Vercel
Now we need to give Vercel the configuration it needs to connect to Blogree.
- In your Vercel project, go to Settings → Environment Variables
- Add the following environment variables:
BLOGREE_WEBHOOK_SECRET=whs_your_secret_here
BLOGREE_BUILD_HOOK_URL=https://api.vercel.com/v1/integrations/deploy/abc...Where to find each value:
- BLOGREE_WEBHOOK_SECRET: Go to Blogree Dashboard → Sites → Your Site → Settings. Copy the
Webhook Secret(starts withwhs_) - BLOGREE_BUILD_HOOK_URL: Copy the Vercel Deploy Hook URL you created in Step 3
Step 5: Get Your Webhook URL
Your Vercel Serverless Function now has a public URL. It follows this pattern:
https://your-vercel-project.vercel.app/api/blogreeReplace your-vercel-project with your actual Vercel project name.
For example:
- If your site is
https://myblog.vercel.app, your webhook URL is:https://myblog.vercel.app/api/blogree - If you have a custom domain like
https://myblog.com, your webhook URL is:https://myblog.com/api/blogree
Step 6: Connect Blogree to Vercel
Now tell Blogree where to send your webhook:
- Go to your Blogree Dashboard
- Go to Sites and select your Vercel site
- Go to Settings
- Find the Webhook URL field
- Paste your webhook URL (from Step 5)
- Make sure the Webhook Secret matches the environment variable you set in Vercel
- Click Save
Step 7: Test Your Integration
Let's verify everything is working:
- In Blogree, go to your site Settings
- Click Test Delivery or Test Webhook
- You should see a success message and a new deployment should start in Vercel
To verify the deployment:
- Go to your Vercel Dashboard
- Click on your project
- You should see a new deployment starting
- After 1-2 minutes, the deployment should be complete ✅
Step 8: Publish Your First Post
You're all set! Now let's test with a real post:
- In Blogree, create and publish a new post
- Wait 10-15 seconds for Vercel to rebuild
- Go to your website
- Your new post should appear! ✅
What Happens With Each Action
Publishing a Post
- Blogree sends a webhook to your function
- Your function verifies the signature
- Your function triggers a Vercel deployment
- Vercel rebuilds your site with the new post
- Post appears on your website ✅
Updating a Post
- Blogree sends an update webhook
- Your function triggers a rebuild
- Vercel rebuilds with the updated content
- Changes appear on your website ✅
Deleting a Post
- Blogree sends a deletion webhook
- Your function triggers a rebuild
- Vercel rebuilds without the deleted post
- Post disappears from your website ✅
Troubleshooting
The test webhook fails with "Invalid signature"
Your BLOGREE_WEBHOOK_SECRET environment variable doesn't match the one in Blogree. Go back to Step 4 and verify they match exactly (including the whs_ prefix with no extra spaces).
The webhook succeeds but Vercel doesn't rebuild
Your BLOGREE_BUILD_HOOK_URL might be incorrect. Go back to your Vercel Deploy Hooks settings and copy the URL again, making sure there are no typos.
Posts aren't appearing on my site
Check that your Vercel build process properly fetches posts from Blogree. Make sure your build script is configured correctly in vercel.json.
I see deployment errors in Vercel
Check your build logs in Vercel Dashboard. The rebuild might be failing due to your build configuration or missing environment variables needed for your site.
Nothing is happening when I publish a post
Check these things:
- Are both environment variables set in Vercel? (BLOGREE_WEBHOOK_SECRET and BLOGREE_BUILD_HOOK_URL)
- Does your webhook URL match what's in Blogree Settings?
- Try clicking "Test Webhook" in Blogree and check your Vercel function logs
- Go to Vercel Dashboard → Your Project → View Function Logs to see what's happening