Documentation Index Fetch the complete documentation index at: https://docs.useinvent.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Add your Invent AI assistant to any Gatsby site. Perfect for static websites built with React and GraphQL.
Installation
Install React Helmet
npm install react-helmet gatsby-plugin-react-helmet
Configure gatsby-config.js
Add the plugin to your gatsby-config.js: module . exports = {
plugins: [
'gatsby-plugin-react-helmet' ,
// ... other plugins
],
};
Create Assistant Component
// src/components/InventAssistant.tsx
import React from 'react' ;
interface InventAssistantProps {
assistantId : string ;
themeAppearance ?: 'auto' | 'light' | 'dark' ;
themeButtonBackgroundColor ?: string ;
themeButtonColor ?: string ;
userId ?: string ;
userName ?: string ;
userHash ?: string ;
userAvatar ?: string ;
}
const InventAssistant : React . FC < InventAssistantProps > = ({
assistantId ,
themeAppearance = 'auto' ,
themeButtonBackgroundColor ,
themeButtonColor ,
userId ,
userName ,
userHash ,
userAvatar ,
}) => {
return (
<>
< invent-assistant
assistant-id = { assistantId }
theme-appearance = { themeAppearance }
{ ... ( themeButtonBackgroundColor && {
'theme-button-background-color' : themeButtonBackgroundColor ,
}) }
{ ... ( themeButtonColor && {
'theme-button-color' : themeButtonColor ,
}) }
{ ... ( userId && { 'user-id' : userId }) }
{ ... ( userName && { 'user-name' : userName }) }
{ ... ( userHash && { 'user-hash' : userHash }) }
{ ... ( userAvatar && { 'user-avatar' : userAvatar }) }
/>
< script
type = "text/javascript"
src = "https://www.useinvent.com/button.js"
async
defer
/>
</>
);
};
export default InventAssistant ;
Add to Layout
// src/components/layout.tsx
import React from 'react' ;
import InventAssistant from './InventAssistant' ;
const Layout : React . FC <{ children : React . ReactNode }> = ({ children }) => {
return (
<>
< main > { children } </ main >
< InventAssistant assistantId = { process . env . GATSBY_INVENT_ASSISTANT_ID ! } />
</>
);
};
export default Layout ;
Add Environment Variable
Create .env.development and .env.production: GATSBY_INVENT_ASSISTANT_ID = ast_YOUR_ASSISTANT_ID
User Authentication
Security Requirement: When using any user-* attributes (user-id, user-name, user-avatar), you must also provide user-hash. Both user-id and user-hash must be provided together, or neither should be provided. The user-hash must be generated on your backend using HMAC-SHA256 with your assistant’s secret key. Never expose the secret key to the client.
Using Gatsby Functions (Serverless)
Gatsby Functions allow you to generate the hash server-side:
// src/api/user-hash.ts
import type { GatsbyFunctionRequest , GatsbyFunctionResponse } from 'gatsby' ;
import crypto from 'crypto' ;
export default function handler (
req : GatsbyFunctionRequest ,
res : GatsbyFunctionResponse
) {
// Get user from your auth system
const userId = req . headers [ 'x-user-id' ];
if ( ! userId ) {
return res . status ( 401 ). json ({ error: 'Unauthorized' });
}
const secretKey = process . env . INVENT_SECRET_KEY ! ;
const userHash = crypto
. createHmac ( 'sha256' , secretKey )
. update ( userId as string )
. digest ( 'hex' );
return res . json ({
userId ,
userHash ,
});
}
Fetching User Data
// src/components/InventAssistantWrapper.tsx
import React , { useEffect , useState } from 'react' ;
import InventAssistant from './InventAssistant' ;
const InventAssistantWrapper : React . FC = () => {
const [ userData , setUserData ] = useState <{
userId ?: string ;
userName ?: string ;
userHash ?: string ;
userAvatar ?: string ;
} | null >( null );
useEffect (() => {
fetch ( '/api/user-hash' )
. then (( res ) => res . json ())
. then ( setUserData )
. catch ( console . error );
}, []);
return (
< InventAssistant
assistantId = { process . env . GATSBY_INVENT_ASSISTANT_ID ! }
{ ... userData }
/>
);
};
export default InventAssistantWrapper ;
GraphQL Integration
Pass content data to provide context:
// src/templates/blog-post.tsx
import React , { useEffect } from 'react' ;
import { graphql } from 'gatsby' ;
import Layout from '../components/layout' ;
const BlogPost : React . FC <{ data : any }> = ({ data }) => {
const post = data . markdownRemark ;
useEffect (() => {
if ( typeof window !== 'undefined' ) {
window . inventContext = {
pageType: 'blog-post' ,
title: post . frontmatter . title ,
author: post . frontmatter . author ,
category: post . frontmatter . category ,
};
}
}, [ post ]);
return (
< Layout >
< article >
< h1 > { post . frontmatter . title } </ h1 >
< div dangerouslySetInnerHTML = { { __html: post . html } } />
</ article >
</ Layout >
);
};
export const query = graphql `
query($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
html
frontmatter {
title
author
category
}
}
}
` ;
export default BlogPost ;
TypeScript Support
Add type declarations:
// src/types/invent-assistant.d.ts
declare namespace JSX {
interface IntrinsicElements {
'invent-assistant' : {
'assistant-id' : string ;
'theme-appearance' ?: 'auto' | 'light' | 'dark' ;
'theme-button-background-color' ?: string ;
'theme-button-color' ?: string ;
'user-id' ?: string ;
'user-name' ?: string ;
'user-hash' ?: string ;
'user-avatar' ?: string ;
};
}
}
interface Window {
inventContext ?: Record < string , any >;
}
Tips for Gatsby
Serverless Functions Use Gatsby Functions for hash generation
GraphQL Context Pass content data for better context
Static & Dynamic Works with SSG and DSG builds
Plugin Ecosystem Integrates with Gatsby plugins
Troubleshooting
Script loading multiple times
Solutions:
Check gatsby-browser.js for duplicate script logic
Use conditional to prevent duplicate loads
Clear .cache and public folders: gatsby clean
Environment variables not working
Solutions:
Prefix public variables with GATSBY_
Restart development server
Check .env files exist
Verify gatsby-config.js is reading variables
Solutions:
Ensure typeof window checks for SSR
Use dynamic imports if needed
Check all dependencies are installed
Clear cache: gatsby clean
Best Practices
Use Gatsby Functions for server-side operations
Always check for window before accessing it
Store secret keys in .env files (never commit)
Use GATSBY_ prefix only for public variables
Test both development and production builds