Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Intercom

To integrate Intercom with Bolt.new, add the Intercom JavaScript snippet to your root layout using your app ID — the Messenger widget loads immediately in the WebContainer preview. For REST API features (managing contacts, conversations, articles), create a Next.js API route that uses your Intercom API access token stored in server-side environment variables. Webhooks for real-time conversation events require a deployed URL on Netlify or Bolt Cloud.

What you'll learn

  • How to install and configure the Intercom Messenger widget in a Bolt.new Next.js app
  • How to identify logged-in users to Intercom so messaging is personalized
  • How to use the Intercom REST API through a Next.js API route to manage contacts and conversations
  • How to send targeted messages and create articles in the Intercom Help Center via API
  • Why Intercom webhooks require a deployed URL and how to configure them after deploying
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate15 min read20 minutesCommunicationApril 2026RapidDev Engineering Team
TL;DR

To integrate Intercom with Bolt.new, add the Intercom JavaScript snippet to your root layout using your app ID — the Messenger widget loads immediately in the WebContainer preview. For REST API features (managing contacts, conversations, articles), create a Next.js API route that uses your Intercom API access token stored in server-side environment variables. Webhooks for real-time conversation events require a deployed URL on Netlify or Bolt Cloud.

Integrating Intercom's Customer Engagement Platform with Bolt.new

Intercom is more than a live chat widget — it combines real-time Messenger, AI-powered Resolution Bot, targeted in-app messages, product tours, and a help center into a single platform. For Bolt.new developers building SaaS products, Intercom is particularly valuable because its JavaScript API allows you to identify users, track custom events, and trigger targeted messages programmatically, turning it into a lightweight CRM layer on top of your existing app.

The integration in Bolt.new follows the same two-layer pattern as most JavaScript-based tools. The Messenger widget embeds via a small JavaScript snippet in your root layout, loads asynchronously from Intercom's CDN, and works in Bolt's WebContainer preview from the first moment you configure it. The widget requires only your Intercom app ID (a public identifier) to initialize, making it one of the simplest integrations to get running. Once loaded, you can call the Intercom JavaScript API to pass user data — name, email, account creation date, custom attributes — so Intercom users see a complete customer profile before responding.

For operations beyond the widget — reading conversation history, managing contacts, creating help center articles, or triggering automated messages — you use Intercom's REST API through a server-side Next.js API route. These calls use your Intercom API access token, which must stay server-side. Webhooks for real-time events (conversation started, message received, user created) require Intercom to POST to your server, which means they only work after deploying to Netlify or Bolt Cloud. Plan your architecture around this: use the widget for synchronous interactions and webhooks for event-driven automations that don't block the user experience.

Integration method

Bolt Chat + API Route

Intercom integrates with Bolt.new through two main channels: the Intercom Messenger JavaScript snippet that embeds the chat widget directly into your app (works in WebContainer preview), and the Intercom REST API accessed through Next.js API routes for managing contacts, conversations, and help center articles. The Messenger widget is the primary integration path — configure your app ID, optionally pass user identity data, and the widget handles the rest. Advanced automation and contact management use the REST API with an access token stored securely in server-side environment variables.

Prerequisites

  • An Intercom account (14-day free trial, paid plans start at $74/month for the Starter plan)
  • Your Intercom app ID (found in Settings → Installation → Your app ID — a short alphanumeric string)
  • An Intercom API access token (Settings → Developers → API Keys → Your app → Access Token)
  • A Bolt.new project using Next.js for server-side API routes
  • For webhooks and OAuth: a deployed URL from Netlify or Bolt Cloud (webhooks cannot reach the WebContainer preview)

Step-by-step guide

1

Get Your Intercom App ID and API Access Token

Intercom requires two separate credentials: a public app ID for the Messenger widget and a private access token for the REST API. To find your app ID, log into Intercom and go to Settings → Installation. At the top of the page, you'll see your app ID displayed as a short string like 'abc123xy'. This is public and safe to include in client-side code — it only identifies which Intercom workspace the widget connects to. For the REST API, go to Settings → Developers → API Keys. If you have developer hub access, click on your app (or create one). Under 'Authentication', you'll find your Access Token. If you're on a newer Intercom plan, you may need to create a developer app first: go to developers.intercom.com, sign in, click 'New app', give it a name, and select your workspace. Your access token appears in the Authentication section. This token has full API access — treat it like a password. Store it only as a server-side environment variable without the NEXT_PUBLIC_ prefix.

Pro tip: Intercom's access tokens do not expire unless you revoke them. Create a dedicated token for each application so you can revoke individual app access without affecting other integrations.

Expected result: You have your Intercom app ID (short alphanumeric string) and your API access token (a long alphanumeric string) saved for configuration.

2

Embed the Intercom Messenger Widget

The Intercom Messenger is embedded by calling the window.Intercom() function with your app ID and optional user data. In a Next.js app, you add a client-side component to your root layout that initializes Intercom after the page loads. The initialization call accepts a configuration object where you can set the app_id (required), and optionally provide user identity information: name, email, user_id, and created_at (Unix timestamp). When user data is provided, Intercom shows the agent a complete customer profile. For anonymous visitors, omit user data and Intercom shows the Messenger in 'visitor' mode. The widget loads from Intercom's CDN and appears as a colored circle in the bottom-right corner. It includes the entire Messenger experience — live chat, help center articles, and automated bots — in a single initialization. This works fully in Bolt's WebContainer preview, so you can test the complete chat flow during development. To hide the widget on certain pages (like login or checkout), call window.Intercom('update', { hide_default_launcher: true }) in a useEffect for that page.

Bolt.new Prompt

Create an IntercomProvider client component in components/IntercomProvider.tsx that initializes Intercom. It should load the Intercom JavaScript snippet for app ID from process.env.NEXT_PUBLIC_INTERCOM_APP_ID, support passing user data (name, email, userId, createdAt as Unix timestamp) as props for authenticated users, and call Intercom('shutdown') when the component unmounts or when user logs out. Add this component to app/layout.tsx wrapping the page content.

Paste this in Bolt.new chat

components/IntercomProvider.tsx
1'use client';
2import { useEffect } from 'react';
3
4interface IntercomProviderProps {
5 children: React.ReactNode;
6 user?: {
7 id: string;
8 email: string;
9 name: string;
10 createdAt: number; // Unix timestamp
11 };
12}
13
14declare global {
15 interface Window {
16 Intercom?: (command: string, data?: Record<string, unknown>) => void;
17 intercomSettings?: Record<string, unknown>;
18 }
19}
20
21export function IntercomProvider({ children, user }: IntercomProviderProps) {
22 const appId = process.env.NEXT_PUBLIC_INTERCOM_APP_ID!;
23
24 useEffect(() => {
25 // Load Intercom script
26 (function () {
27 const w = window;
28 const ic = w.Intercom;
29 if (typeof ic === 'function') {
30 ic('reattach_activator');
31 ic('update', w.intercomSettings);
32 } else {
33 const d = document;
34 const i = function (...args: unknown[]) {
35 (i as unknown as { q: unknown[] }).q.push(args);
36 };
37 (i as unknown as { q: unknown[]; c: (...args: unknown[]) => void }).q = [];
38 (i as unknown as { c: (...args: unknown[]) => void }).c = function (...args: unknown[]) {
39 (i as unknown as { q: unknown[] }).q.push(args);
40 };
41 w.Intercom = i as unknown as (command: string, data?: Record<string, unknown>) => void;
42 const l = function () {
43 const s = d.createElement('script');
44 s.type = 'text/javascript';
45 s.async = true;
46 s.src = `https://widget.intercom.io/widget/${appId}`;
47 const x = d.getElementsByTagName('script')[0];
48 x?.parentNode?.insertBefore(s, x);
49 };
50 if (document.readyState === 'complete') {
51 l();
52 } else {
53 window.addEventListener('load', l);
54 }
55 }
56 })();
57
58 // Initialize with user data or anonymous
59 const config: Record<string, unknown> = { app_id: appId };
60 if (user) {
61 config.user_id = user.id;
62 config.email = user.email;
63 config.name = user.name;
64 config.created_at = user.createdAt;
65 }
66 window.Intercom?.('boot', config);
67
68 return () => {
69 window.Intercom?.('shutdown');
70 };
71 }, [appId, user?.id]);
72
73 return <>{children}</>;
74}

Pro tip: Pass createdAt as a Unix timestamp (seconds since epoch), not milliseconds. Use Math.floor(new Date(user.createdAt).getTime() / 1000) to convert a JavaScript Date to the correct format.

Expected result: The Intercom Messenger bubble appears in the bottom-right corner of your Bolt preview. Opening it shows the Messenger with help center articles and a live chat option. Authenticated users appear in Intercom with their name and email.

3

Create API Routes for Intercom REST API

Intercom's REST API provides access to contacts, conversations, articles, and more. All calls require a Bearer token authorization header using your access token. Create API routes in Next.js that proxy requests to Intercom's API, keeping the token server-side. The Intercom API is versioned — always include the Intercom-Version header to pin to a specific API version and prevent breaking changes when Intercom releases updates. Key endpoints you'll likely need: GET /contacts to search and filter your contact list, GET /conversations to fetch conversation history, GET /articles to retrieve help center articles. The Intercom API uses cursor-based pagination with a starting_after parameter for large result sets. For most Bolt apps, the most valuable REST API operations are fetching conversation history for a specific user (filtering by email), creating or updating contact records with custom attributes, and reading help center articles for a search feature.

Bolt.new Prompt

Create a Next.js API route at /api/intercom/contacts that accepts GET requests with an optional email query parameter. If email is provided, search Intercom's Contacts API for contacts with that email using INTERCOM_ACCESS_TOKEN. Set the Intercom-Version header to '2.10'. Return the matching contacts with their id, name, email, created_at, and any custom attributes. Also create /api/intercom/conversations that fetches open conversations filtered by a contact_id query parameter.

Paste this in Bolt.new chat

app/api/intercom/contacts/route.ts
1// app/api/intercom/contacts/route.ts
2import { NextResponse } from 'next/server';
3
4const INTERCOM_API_BASE = 'https://api.intercom.io';
5const INTERCOM_VERSION = '2.10';
6
7function getHeaders() {
8 return {
9 Authorization: `Bearer ${process.env.INTERCOM_ACCESS_TOKEN}`,
10 'Intercom-Version': INTERCOM_VERSION,
11 'Content-Type': 'application/json',
12 Accept: 'application/json',
13 };
14}
15
16export async function GET(request: Request) {
17 const { searchParams } = new URL(request.url);
18 const email = searchParams.get('email');
19
20 try {
21 let url = `${INTERCOM_API_BASE}/contacts`;
22 if (email) {
23 // Search by email using filter
24 url = `${INTERCOM_API_BASE}/contacts/search`;
25 const body = JSON.stringify({
26 query: {
27 operator: 'AND',
28 value: [{ field: 'email', operator: '=', value: email }],
29 },
30 });
31 const response = await fetch(url, {
32 method: 'POST',
33 headers: getHeaders(),
34 body,
35 });
36 const data = await response.json();
37 return NextResponse.json(data);
38 }
39
40 const response = await fetch(url, { headers: getHeaders() });
41 const data = await response.json();
42 return NextResponse.json(data);
43 } catch (error: unknown) {
44 const e = error as { message: string };
45 return NextResponse.json({ error: e.message }, { status: 500 });
46 }
47}

Pro tip: Intercom enforces rate limits of 1,000 requests per minute. For dashboard pages that make multiple API calls, consider caching responses in memory or using React Query's staleWhileRevalidate pattern to avoid hitting limits.

Expected result: GET to /api/intercom/contacts?email=user@example.com returns matching Intercom contact records. The access token stays server-side and never appears in the browser.

4

Deploy and Configure Intercom Webhooks

The Messenger widget and REST API polling work in Bolt's WebContainer preview. For real-time event processing — reacting when a user starts a conversation, sends a message, or is created — you need Intercom webhooks. Intercom sends POST requests to your webhook URL when these events fire. Since Bolt's WebContainer has no publicly accessible URL, webhook payloads cannot be delivered during development. Deploy to Netlify or Bolt Cloud first. After deploying, go to the Intercom Developer Hub (developers.intercom.com), select your app, go to Webhooks, and add your webhook URL (e.g., https://your-app.netlify.app/api/intercom/webhook). Select the topics you want to subscribe to — 'conversation.created', 'conversation.user.replied', and 'contact.created' are the most commonly used. Intercom signs webhook payloads with a secret from your app settings. Validate this signature in your webhook handler to confirm events come from Intercom and not from spoofed requests. Intercom retries failed webhooks up to 10 times over 8 hours, so your handler should respond quickly with 200 and process the event asynchronously.

Bolt.new Prompt

Create an Intercom webhook handler at /api/intercom/webhook that receives POST requests. Verify the X-Hub-Signature header using the INTERCOM_WEBHOOK_SECRET environment variable (HMAC-SHA1 of the raw request body). Handle these event types: 'conversation.created' (log new conversation with user details), 'conversation.user.replied' (save the message to database), and 'contact.created' (trigger a welcome email flow). Always respond with 200 status after recording the event.

Paste this in Bolt.new chat

app/api/intercom/webhook/route.ts
1// app/api/intercom/webhook/route.ts
2import { NextResponse } from 'next/server';
3import crypto from 'crypto';
4
5export async function POST(request: Request) {
6 const rawBody = await request.text();
7 const signature = request.headers.get('X-Hub-Signature');
8
9 // Verify webhook signature
10 if (process.env.INTERCOM_WEBHOOK_SECRET && signature) {
11 const expectedSig = crypto
12 .createHmac('sha1', process.env.INTERCOM_WEBHOOK_SECRET)
13 .update(rawBody)
14 .digest('hex');
15 if (`sha1=${expectedSig}` !== signature) {
16 return NextResponse.json({ error: 'Invalid signature' }, { status: 403 });
17 }
18 }
19
20 try {
21 const payload = JSON.parse(rawBody);
22 const { topic, data } = payload;
23
24 switch (topic) {
25 case 'conversation.created':
26 console.log('New conversation:', data.item.id);
27 break;
28 case 'conversation.user.replied':
29 console.log('User replied to conversation:', data.item.id);
30 break;
31 case 'contact.created':
32 console.log('New contact created:', data.item.email);
33 break;
34 default:
35 console.log('Unhandled Intercom event:', topic);
36 }
37
38 return NextResponse.json({ received: true });
39 } catch (error: unknown) {
40 const e = error as { message: string };
41 return NextResponse.json({ error: e.message }, { status: 500 });
42 }
43}

Pro tip: Intercom webhooks use HMAC-SHA1 (not SHA-256) for signature verification — a common source of verification failures when developers assume SHA-256.

Expected result: After deploying and configuring webhooks in the Intercom Developer Hub, conversation events trigger your webhook handler. The Intercom developer console shows successful 200 responses for each delivery.

Common use cases

Personalized Onboarding Messenger with User Identification

Add Intercom Messenger to your SaaS app and identify authenticated users so support agents see their name, email, account age, and plan tier before the conversation starts. Trigger a welcome message when new users log in for the first time to guide them through key features.

Bolt.new Prompt

Add Intercom Messenger to my Next.js app. In the root layout, load the Intercom JavaScript snippet with my app ID from process.env.NEXT_PUBLIC_INTERCOM_APP_ID. Create a client component IntercomProvider that initializes Intercom with the current user's name, email, userId, and created_at date when they're logged in, and calls Intercom('shutdown') on logout. Show a custom welcome message for users whose account is less than 7 days old: 'Welcome! Need help getting started? I'm here to help.'

Copy this prompt to try it in Bolt.new

Help Center Article Search Widget

Build a search feature that queries your Intercom Help Center articles through the REST API and displays results inline in your app, allowing users to find answers without opening the full Messenger. When an article doesn't answer the question, provide a button to open Messenger with the search query pre-filled.

Bolt.new Prompt

Create a help search component that calls /api/intercom/articles?query=search_term to search my Intercom Help Center articles. The API route should call Intercom's Articles REST API with INTERCOM_ACCESS_TOKEN. Display up to 5 matching articles as cards with title, summary, and a 'Read more' link that opens in a new tab. Add a 'Still need help? Chat with us' button at the bottom that opens Intercom Messenger with window.Intercom('showNewMessage', 'I searched for: ' + query) pre-populated.

Copy this prompt to try it in Bolt.new

Customer Conversation Dashboard

Build an internal dashboard that shows your team all open Intercom conversations, their status, assigned agent, and time since last reply. The dashboard pulls data from the Intercom Conversations API through a server-side API route, giving your support team a quick overview without logging into Intercom's admin interface.

Bolt.new Prompt

Create an admin page at /admin/conversations that fetches all open Intercom conversations via /api/intercom/conversations. The API route should call Intercom's Conversations API using INTERCOM_ACCESS_TOKEN, filtering for open conversations only. Display results as a table with columns: customer name, subject/first message, assigned agent, status, and time since last reply. Color-code rows where the last reply was over 4 hours ago in red. Add a 'View in Intercom' link for each conversation.

Copy this prompt to try it in Bolt.new

Troubleshooting

Intercom Messenger widget doesn't appear in the app

Cause: The most common causes are an incorrect app ID, a content security policy blocking Intercom's CDN, or the boot() call firing before the Intercom script fully loads.

Solution: Open browser DevTools → Console and look for Intercom errors. Type window.Intercom to check if the function exists — if it returns undefined, the script didn't load. Verify NEXT_PUBLIC_INTERCOM_APP_ID is set correctly (no quotes, exact value from Intercom). Check the Network tab for failed requests to widget.intercom.io. If the script loads but the widget doesn't appear, make sure Intercom('boot', { app_id: 'YOUR_ID' }) is being called after the script loads.

typescript
1// Debug in browser console:
2console.log('App ID:', process.env.NEXT_PUBLIC_INTERCOM_APP_ID);
3console.log('Intercom function:', typeof window.Intercom);
4window.Intercom?.('boot', { app_id: 'YOUR_ACTUAL_ID' });

Intercom REST API returns 401 Unauthorized

Cause: The API access token is missing, expired, or incorrectly formatted in the Authorization header. Intercom tokens use Bearer authentication, not Basic auth.

Solution: Verify INTERCOM_ACCESS_TOKEN is set in your .env file. The Authorization header must be 'Bearer YOUR_TOKEN' — the 'Bearer ' prefix is required. Check that the token hasn't been revoked in Settings → Developers → API Keys. Confirm you're using the correct token for the workspace (Intercom tokens are workspace-specific).

typescript
1// Correct header format:
2headers: {
3 Authorization: `Bearer ${process.env.INTERCOM_ACCESS_TOKEN}`, // Note: Bearer, not Basic
4 'Intercom-Version': '2.10',
5}

Intercom webhook signature verification fails (403 response)

Cause: The webhook secret is wrong, or you're parsing the body with request.json() before signature verification — this changes the raw bytes used for the HMAC calculation.

Solution: Always read the raw body with request.text() before computing the HMAC signature, then parse the JSON separately. The HMAC must be computed on the raw request body bytes, not a re-serialized JSON object. Verify INTERCOM_WEBHOOK_SECRET matches exactly what's shown in your Intercom app's webhook settings.

typescript
1// Correct order: read raw text FIRST, then parse
2const rawBody = await request.text();
3const signature = request.headers.get('X-Hub-Signature');
4// Verify signature using rawBody
5const payload = JSON.parse(rawBody); // Parse AFTER verification

Webhooks work in testing but never fire in production

Cause: This is the WebContainer limitation. Bolt's WebContainer has no public URL for Intercom to call during development. Testing 'works' in the Intercom developer console's test webhook feature but actual events never arrive.

Solution: Deploy to Netlify or Bolt Cloud first. Then update your Intercom webhook URL to your deployed domain (e.g., https://your-app.netlify.app/api/intercom/webhook). Webhooks require a publicly accessible HTTPS endpoint — the WebContainer cannot provide this.

Best practices

  • Store INTERCOM_ACCESS_TOKEN as a server-side environment variable (no NEXT_PUBLIC_ prefix) — it provides full access to your contact database and conversation history
  • Initialize Intercom with user identity data (name, email, user_id) for authenticated users so agents always have context before responding
  • Call Intercom('shutdown') when users log out to prevent the next user on the same device from seeing the previous user's conversation history
  • Use the hide_default_launcher option on authentication pages (login, signup) and checkout flows to avoid distracting the user at critical conversion moments
  • Proxy all Intercom REST API calls through Next.js API routes and never call Intercom's API directly from client components
  • Pin the Intercom API version with the Intercom-Version header to avoid unexpected breaking changes from automatic version upgrades
  • Respond to Intercom webhooks within 30 seconds with a 200 status — use async processing for heavy operations to avoid timeouts and retry storms
  • Test the Messenger widget in Bolt's WebContainer preview, but deploy before testing webhooks, OAuth flows, or any inbound HTTP event handling

Alternatives

Frequently asked questions

Does Intercom Messenger work in Bolt's WebContainer preview?

Yes. The Intercom Messenger widget is a JavaScript snippet that loads from Intercom's CDN — it works in Bolt's WebContainer preview exactly as it would on any website. You can test the full chat experience, send messages, and see them in your Intercom inbox during development. The limitation is webhooks: incoming events from Intercom require a deployed URL and won't be delivered to the WebContainer.

How do I find my Intercom app ID?

Log into Intercom, go to Settings → Installation, and look for the JavaScript snippet. Your app ID appears in the snippet as 'app_id: YOUR_APP_ID' — it's a short alphanumeric string like 'abc123xy'. You can also find it in the URL when you're in your Intercom workspace: app.intercom.com/a/apps/YOUR_APP_ID. The app ID is public and safe to include in client-side code.

What's the difference between Intercom's app ID and API access token?

The app ID is a public identifier used by the Messenger JavaScript snippet to connect the widget to your Intercom workspace — it's safe to expose in client code. The API access token is a private credential used for REST API calls (reading contacts, conversations, articles) — it must be kept server-side in environment variables. Never use your API access token in client-side JavaScript.

Can I identify users in Intercom without writing custom code?

Yes, for basic identification. Pass name, email, and user_id directly to the Intercom('boot') call when the user logs in. For verified identity (preventing users from spoofing other users' identities), Intercom provides Identity Verification — generate an HMAC hash of the user's ID server-side using your Identity Verification secret and pass it as the user_hash parameter in the boot call.

How much does Intercom cost for a new Bolt.new app?

Intercom's Starter plan costs $74/month and includes the Messenger, help center, basic automation, and up to 3 seats. The Essential plan for growing teams starts at $169/month. Intercom offers a 14-day free trial with full feature access. For early-stage Bolt apps, Intercom's pricing is one of the higher entry points compared to alternatives like LiveChat or Freshdesk.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.