Netlify Integration
Connect your Netlify-hosted site to Blogree for automatic rebuilds and deployments. Whenever you publish, update, or delete a post in Blogree, your Netlify site will automatically rebuild with the latest content.
Perfect for: Gatsby, Next.js, Hugo, Nuxt, or any static site generator deployed to Netlify.
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 signed webhook to your Netlify Function
- Your Netlify Function verifies the signature (security check)
- Your Netlify Function triggers a Netlify build hook
- Netlify automatically rebuilds your site
- Your site deploys with the new content ✅
Step 1: Get Your Blogree Credentials
First, collect the keys you'll need from Blogree:
- Log in to your Blogree Dashboard
- Go to Sites and select your site
- Go to Settings
- Copy these two values:
- Webhook Secret
- Pull API Key
Keep these safe — you'll need them in the next steps.
Step 2: Create a Netlify Build Hook
A build hook is a URL that tells Netlify to rebuild your site. Let's create one:
- Go to your Netlify Dashboard
- Select your site
- Go to Site Settings → Build & Deploy → Build Hooks
- Click Add build hook
- Name it Blogree
- Select your main branch (usually
mainormaster) - Click Save
- Copy the hook URL (it looks like:
https://api.netlify.com/build_hooks/abc123xyz...)
Step 3: Add the Webhook Function
Now we need to add a Netlify Function that receives webhooks from Blogree and triggers rebuilds.
In your project root, create the folder structure:
netlify/
functions/
blogree-webhook.jsCreate the file netlify/functions/blogree-webhook.js with this code:
/**
* Netlify Function: blogree-webhook.js
* Receives Blogree webhooks and triggers site rebuilds
*/
const crypto = require('crypto');
const https = require('https');
const http = require('http');
// Configuration from environment variables
const CONFIG = {
webhookSecret: process.env.BLOGREE_WEBHOOK_SECRET,
buildHookUrl: process.env.BLOGREE_BUILD_HOOK_URL,
apiUrl: process.env.BLOGREE_API_URL,
apiKey: process.env.BLOGREE_API_KEY,
};
// Verify Blogree signature
function verifySignature(rawBody, signatureHeader) {
if (!CONFIG.webhookSecret) {
console.log('[Blogree] Warning: BLOGREE_WEBHOOK_SECRET not set');
return true;
}
if (!signatureHeader) {
console.log('[Blogree] Error: Missing X-Blogree-Signature header');
return false;
}
const expected = 'sha256=' + crypto
.createHmac('sha256', CONFIG.webhookSecret)
.update(rawBody)
.digest('hex');
try {
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected)
);
} catch {
console.log('[Blogree] Signature verification failed');
return false;
}
}
// Trigger Netlify build
function triggerBuild(postSlug) {
return new Promise((resolve, reject) => {
if (!CONFIG.buildHookUrl) {
console.log('[Blogree] Warning: BLOGREE_BUILD_HOOK_URL not set');
return resolve({ skipped: true });
}
console.log(`[Blogree] Triggering rebuild for post: ${postSlug}`);
const url = new URL(CONFIG.buildHookUrl);
const client = url.protocol === 'https:' ? https : http;
const req = client.request(
{
hostname: url.hostname,
path: url.pathname + url.search,
method: 'POST',
headers: { 'Content-Length': 0 },
},
(res) => {
console.log(`[Blogree] Build triggered — Status: ${res.statusCode}`);
resolve({ status: res.statusCode });
}
);
req.on('error', reject);
req.setTimeout(10000, () => {
req.destroy();
reject(new Error('Build hook timeout'));
});
req.end();
});
}
// Main Netlify Function handler
exports.handler = async (event) => {
// Only accept POST requests
if (event.httpMethod !== 'POST') {
return {
statusCode: 405,
body: JSON.stringify({ error: 'Method not allowed' }),
};
}
try {
// Get raw body (important for signature verification)
const rawBody = event.isBase64Encoded
? Buffer.from(event.body, 'base64').toString('utf8')
: event.body || '';
const signature = event.headers['x-blogree-signature'] || '';
console.log('[Blogree] Webhook received');
// Verify signature
if (!verifySignature(rawBody, signature)) {
console.log('[Blogree] Invalid signature - rejecting');
return {
statusCode: 401,
body: JSON.stringify({ error: 'Invalid signature' }),
};
}
// Parse payload
let payload;
try {
payload = JSON.parse(rawBody);
} catch {
console.log('[Blogree] Invalid JSON payload');
return {
statusCode: 400,
body: JSON.stringify({ error: 'Invalid JSON' }),
};
}
// Extract post info
const postSlug = payload.post?.slug || 'unknown';
const event_type = payload.event || 'unknown';
console.log(`[Blogree] Event: ${event_type} for post: ${postSlug}`);
// Trigger the build
await triggerBuild(postSlug);
return {
statusCode: 200,
body: JSON.stringify({ success: true, message: 'Rebuild triggered' }),
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error('[Blogree] Error:', errorMessage);
return {
statusCode: 500,
body: JSON.stringify({ error: errorMessage }),
};
}
};Step 4: Add Environment Variables
Now tell Netlify about your Blogree and build hook credentials:
- In Netlify Dashboard, go to Site Settings → Build & Deploy → Environment
- Click Edit variables
- Add these four environment variables:
BLOGREE_WEBHOOK_SECRET=whs_your_secret_here
BLOGREE_BUILD_HOOK_URL=https://api.netlify.com/build_hooks/abc123xyz...
BLOGREE_API_URL=https://api.blogree.com
BLOGREE_API_KEY=pk_your_api_key_hereWhere to find each value:
- BLOGREE_WEBHOOK_SECRET: From Step 1 (Blogree Dashboard → Settings)
- BLOGREE_BUILD_HOOK_URL: From Step 2 (Netlify Build Hooks)
- BLOGREE_API_URL:
https://api.blogree.com - BLOGREE_API_KEY: From Step 1 (Blogree Dashboard → Settings)
Click Save after adding all variables.
Step 5: Deploy to Netlify
Push your code to deploy the new Netlify Function:
git add netlify/functions/blogree-webhook.js
git commit -m "Add Blogree webhook function"
git push origin mainNetlify will automatically:
- ✅ Deploy your function
- ✅ Make it available at:
https://your-site.netlify.app/.netlify/functions/blogree-webhook
Step 6: Get Your Webhook URL
After deployment, your Netlify Function is available at this URL:
https://your-site.netlify.app/.netlify/functions/blogree-webhookReplace your-site with your actual Netlify site name.
For example:
- If your site is
https://myblog.netlify.app, your webhook URL is:https://myblog.netlify.app/.netlify/functions/blogree-webhook - If you have a custom domain like
https://myblog.com, your webhook URL is:https://myblog.com/.netlify/functions/blogree-webhook
Step 7: Connect Blogree to Netlify
Now tell Blogree where to send your webhooks:
- Go to your Blogree Dashboard
- Go to Sites and select your site
- Go to Settings
- Find the Webhook URL field
- Paste your webhook URL (from Step 6)
- Make sure the Webhook Secret matches the environment variable in Netlify
- Click Save
Step 8: Test Your Integration
Let's verify everything is working:
- In Blogree, go to your site Settings
- Click Test Webhook or Test Delivery
- You should see a success message
Now check Netlify to verify the rebuild started:
- Go to your Netlify Dashboard
- Click on your site
- Go to Deploys
- You should see a new deploy with status "Building" or "Published"
- Wait for it to complete ✅
To view detailed logs:
- In Netlify Dashboard, go to Functions
- Click on blogree-webhook
- View the function logs to see what happened
Step 9: Publish Your First Post
You're all set! Now test with a real post:
- In Blogree, create and publish a new post
- Wait 1-2 minutes for Netlify to rebuild
- Check your site — the new post should appear! ✅
What Happens With Each Action
Publishing a Post
- Blogree sends a webhook to your Netlify Function
- Function verifies the signature
- Function triggers your Netlify build hook
- Netlify rebuilds your site
- Post appears on your website ✅
Updating a Post
- Blogree sends an update webhook
- Your Netlify Function triggers a rebuild
- Netlify rebuilds with the updated content
- Changes appear on your website ✅
Deleting a Post
- Blogree sends a deletion webhook
- Your Netlify Function triggers a rebuild
- Netlify rebuilds without the deleted post
- Post disappears from your website ✅