AppgramProvider
AppgramProvider - Root provider for Appgram React SDK Supports automatic dark/light theme based on system preference.
Parameters
props AppgramProviderProps Returns
React.ReactElement REACT SDK
Drop-in components and headless hooks for React and Next.js applications.
npm install @appgram/react AppgramProvider - Root provider for Appgram React SDK Supports automatic dark/light theme based on system preference.
props AppgramProviderProps React.ReactElement addSupportMessage async → Promise<ApiResponse<object>> Add a message to a support ticket
ticketId : string token : string content : string checkVote async → Promise<ApiResponse<VoteCheckResponse>> Check if a fingerprint has voted on a wish
wishId : string fingerprint : string checkWaitlistStatus async → Promise<ApiResponse<WaitlistStatus>> Check if an email is on the waitlist
email : string createComment async → Promise<ApiResponse<Comment>> Create a comment
data : object createVote async → Promise<ApiResponse<object>> Create a vote
wishId : string fingerprint : string voterEmail : string optional createWish async → Promise<ApiResponse<Wish>> Create a new wish (feature request)
data : object deleteVote async → Promise<ApiResponse<object>> Delete a vote
voteId : string getBlogCategories async → Promise<ApiResponse<BlogCategory[]>> Get blog categories
getBlogPost async → Promise<ApiResponse<BlogPost>> Get a single blog post by slug
slug : string getBlogPosts async → Promise<ApiResponse<BlogPostsResponse>> Get public blog posts with optional filters
filters : BlogFilters optional getBlogPostsByCategory async → Promise<ApiResponse<BlogPostsResponse>> Get blog posts by category slug
categorySlug : string options : object optional getBlogPostsByTag async → Promise<ApiResponse<BlogPostsResponse>> Get blog posts by tag
tag : string options : object optional getComments async → Promise<ApiResponse<CommentsResponse>> Get comments for a wish
wishId : string options : object optional getContactForm async → Promise<ApiResponse<ContactForm>> Get a contact form by ID via portal endpoint
formId : string getFeaturedBlogPosts async → Promise<ApiResponse<BlogPost[]>> Get featured blog posts
getHelpArticle async → Promise<ApiResponse<HelpArticle>> Get a help article by slug
slug : string flowId : string getHelpCollection async → Promise<ApiResponse<object>> Get help center collection for the project
getHelpFlow async → Promise<ApiResponse<HelpFlow>> Get a help flow by slug
slug : string getPageData async → Promise<ApiResponse<object>> Get all public page data in one request
getPublicForm async → Promise<ApiResponse<ContactForm>> Get a public contact form by ID (legacy endpoint)
formId : string getPublicStatusOverview async → Promise<ApiResponse<StatusPageOverview>> Get public status page overview (services, active updates, overall status)
slug : string getPublicSurvey async → Promise<ApiResponse<Survey & object>> Get a public survey by slug
slug : string getPublicSurveyCustomization async → Promise<ApiResponse<Record<string, unknown>>> Get survey customization settings
surveyId : string getPublicWishes async → Promise<ApiResponse<WishesResponse>> Get public wishes for the project
filters : WishFilters optional getRelatedBlogPosts async → Promise<ApiResponse<BlogPost[]>> Get related blog posts for a given post
slug : string getRelease async → Promise<ApiResponse<Release>> Get a single release by slug
releaseSlug : string getReleaseFeatures async → Promise<ApiResponse<ReleaseFeature[]>> Get features for a release (public endpoint)
releaseSlug : string getReleases async → Promise<ApiResponse<Release[]>> Get public releases for the project
options : object optional getRoadmapData async → Promise<ApiResponse<RoadmapData>> Get roadmap data for the project
getSupportTicket async → Promise<ApiResponse<SupportRequest>> Get a specific support ticket using magic link token
ticketId : string token : string getWaitlistCount async → Promise<ApiResponse<WaitlistCount>> Get the total count of users on the waitlist
getWish async → Promise<ApiResponse<Wish>> Get a single wish by ID
wishId : string joinWaitlist async → Promise<ApiResponse<WaitlistEntry>> Join the waitlist
data : WaitlistJoinInput leaveWaitlist async → Promise<ApiResponse<object>> Leave the waitlist
email : string searchBlogPosts async → Promise<ApiResponse<BlogPostsResponse>> Search blog posts
query : string options : object optional sendSupportMagicLink async → Promise<ApiResponse<object>> Request a magic link to access support tickets
userEmail : string submitContactForm async → Promise<ApiResponse<ContactFormSubmission>> Submit a contact form
projectId : string formId : string data : ContactFormSubmitInput submitSupportRequest async → Promise<ApiResponse<SupportRequest>> Submit a support request
data : SupportRequestInput submitSurveyResponse async → Promise<ApiResponse<SurveyResponse>> Submit a survey response
surveyId : string data : SurveySubmitInput trackContactFormView async → Promise<ApiResponse<object>> Track a contact form view (call when form is displayed)
formId : string uploadFile async → Promise<ApiResponse<object>> Upload a file via public portal (no auth required)
file : File verifySupportToken async → Promise<ApiResponse<object>> Verify magic link token and get user's support tickets
token : string Hook to access the Appgram context
AppgramContextValue options UseBlogCategoriesOptions UseBlogCategoriesResult options UseBlogPostOptions UseBlogPostResult options UseBlogPostsOptions UseBlogPostsResult options UseCommentsOptions UseCommentsResult formId string options UseContactFormOptions UseContactFormResult options UseContactFormSubmitOptions UseContactFormSubmitResult options UseFeaturedPostsOptions UseFeaturedPostsResult options UseHelpArticleOptions UseHelpArticleResult options UseHelpCenterOptions UseHelpCenterResult options UseHelpFlowOptions UseHelpFlowResult options UseReleaseOptions UseReleaseResult options UseReleasesOptions UseReleasesResult options UseRoadmapOptions UseRoadmapResult options UseStatusOptions UseStatusResult options UseSupportOptions UseSupportResult slug string options UseSurveyOptions UseSurveyResult options UseSurveySubmitOptions UseSurveySubmitResult options UseVoteOptions UseVoteResult options UseWaitlistOptions UseWaitlistResult options UseWishOptions UseWishResult options UseWishesOptions UseWishesResult props BlogProps React.ReactElement props BlogCardProps Element props BlogListProps Element props BlogPostDetailProps React.ReactElement | null props ChatWidgetProps React.ReactElement props ContactFormRendererProps React.ReactElement props HelpArticleDetailProps React.ReactElement | null props HelpArticlesProps React.ReactElement | null props HelpCenterProps React.ReactElement props HelpCollectionsProps React.ReactElement props ReleaseCardProps React.ReactElement props ReleaseDetailProps React.ReactElement | null props ReleaseListProps React.ReactElement props ReleasesProps React.ReactElement props RoadmapBoardProps React.ReactElement props RoadmapColumnProps React.ReactElement props StatusBoardProps React.ReactElement props StatusIncidentDetailProps React.ReactElement props SubmitWishFormProps React.ReactElement props SupportFormProps React.ReactElement props SurveyRendererProps React.ReactElement props VoteButtonProps React.ReactElement props WhatsNewPopupProps React.ReactElement | null props WishCardProps React.ReactElement props WishDetailProps React.ReactElement | null props WishListProps React.ReactElement className string optional Custom class name
customFormId string optional Custom form ID to use instead of default form. When provided, fetches the form config and renders its fields dynamically. The form should have integration.type = 'wish' to create feature requests.
description string optional Form description
onError (error: string) => void optional Callback when submission fails
onOpenChange (open: boolean) => void Callback when open state changes
onSuccess (wish: Wish) => void optional Callback when wish is successfully submitted
open boolean Whether the form is open
submitButtonText string optional Submit button text
Default: 'Submit Feature Request'
title string optional Form title
Default: 'Submit a Feature Request'
initialHasVoted boolean optional Initial hasVoted state (optional)
initialVoteCount number optional Initial vote count (optional, useful when you already have the wish data)
onVoteChange (hasVoted: boolean, voteCount: number) => void optional Callback when vote state changes
skipAutoCheck boolean optional Skip automatic vote check on mount to avoid rate limiting When true, vote status will be checked lazily on first interaction
Default: true
voterEmail string optional Voter email (optional, for identified voting)
wishId string The wish ID to vote on
error null | string Error message if any
hasVoted boolean Whether the current user has voted
isChecking boolean Loading state for initial vote check
isLoading boolean Loading state for vote operations
toggle () => Promise<void> Toggle vote (vote if not voted, unvote if voted)
unvote () => Promise<void> Remove a vote
vote () => Promise<void> Cast a vote
voteCount number Current vote count
filters WishFilters optional Initial filters
refreshInterval number optional Auto-refresh interval in milliseconds (0 to disable)
Default: 0
skip boolean optional Skip initial fetch
Default: false
error null | string Error message if any
isLoading boolean Loading state
page number Current page
refetch () => Promise<void> Manually refetch data
setFilters (filters: WishFilters) => void Update filters
setPage (page: number) => void Go to a specific page
total number Total number of wishes
totalPages number Total pages
wishes Wish[] List of wishes
skip boolean optional Skip initial fetch
Default: false
wishId string The wish ID to fetch
error null | string Error message if any
isLoading boolean Loading state
refetch () => Promise<void> Manually refetch data
wish null | Wish The wish data
Vote Types
created_at string fingerprint string id string user_id null | string optional voter_email null | string optional wish_id string className string optional Custom class name
initialHasVoted boolean optional Initial hasVoted state (optional)
initialVoteCount number optional Initial vote count (optional, useful when you already have the wish data)
onVoteChange (hasVoted: boolean, voteCount: number) => void optional Callback when vote state changes
renderContent (props: object) => ReactNode optional Custom render function for the button content
showCount boolean optional Show vote count
Default: true
size 'sm' | 'md' | 'lg' optional Size variant
Default: 'md'
skipAutoCheck boolean optional Skip automatic vote check on mount to avoid rate limiting When true, vote status will be checked lazily on first interaction
Default: true
voterEmail string optional Voter email (optional, for identified voting)
wishId string The wish ID to vote on
has_voted boolean vote_id string optional fingerprint string voter_email string optional wish_id string error null | string optional hasVoted boolean isLoading boolean voteCount number voteId string optional author WishAuthor optional author_email null | string optional author_name null | string optional author_type 'user' | 'anonymous' | 'team_member' category null | Category optional category_id null | string optional comment_count number completed_at null | string optional created_at string description string has_voted boolean optional id string is_pinned boolean optional priority null | WishPriority optional project_id string slug string status WishStatus title string updated_at string vote_count number avatar_url null | string optional email null | string optional name string animationIndex number optional Animation delay index (for staggered animations)
className string optional Custom class name
hasVoted boolean optional Override hasVoted state (for optimistic updates)
isVoting boolean optional Loading state for vote
onClick () => void optional Click handler for the card
onCommentClick () => void optional Comment click handler
onVote (wishId: string, hasVoted: boolean, voteCount: number) => void optional Vote handler
renderVoteButton (props: object) => ReactNode optional Custom render function for the vote button
showAuthor boolean optional Show author
Default: true
showCategory boolean optional Show category badge
Default: true
showCommentCount boolean optional Show comment count
Default: true
showStatus boolean optional Show status badge
Default: true
voteCount number optional Override vote count (for optimistic updates)
wish Wish The wish data
className string optional Custom class name
onCommentAdded (comment: Comment) => void optional Callback when a comment is added
onOpenChange (open: boolean) => void Callback when open state changes
onVote (wishId: string) => void optional Callback when vote is toggled
open boolean Whether the detail view is open
wish null | Wish The wish to display
data Wish[] page number per_page number total number total_pages number category_id string optional fingerprint string optional page number optional per_page number optional priority WishPriority | WishPriority[] optional search string optional sort_by 'votes' | 'created_at' | 'updated_at' optional sort_order 'asc' | 'desc' optional status WishStatus | WishStatus[] optional className string optional Custom class name
description string optional Page description
filters WishFilters optional Initial filters
heading string optional Page heading
headingAlignment 'left' | 'center' | 'right' optional Heading alignment
Default: 'left'
onAddWish () => void optional Handler for adding a new wish
onWishClick (wish: Wish) => void optional Click handler for a wish
refreshInterval number optional Auto-refresh interval in milliseconds
Default: 0
renderEmpty () => ReactNode optional Custom render function for empty state
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
renderWish (wish: Wish, index: number) => ReactNode optional Custom render function for individual wish cards
showSearch boolean optional Show search input
Default: false
variant 'cards' | 'compact' | 'masonry' optional Layout variant
Default: 'cards'
article_type ArticleType content string created_at string excerpt null | string optional flow_id string id string is_published boolean published_at null | string optional slug string sort_order number title string updated_at string article HelpArticle optional The article to display (either pass article object or articleSlug + flowId)
articleSlug string optional Article slug to fetch (alternative to passing article object)
className string optional Custom class name
flow HelpFlow optional The parent flow (for context)
flowId string optional Flow ID for fetching article (required if using articleSlug)
onBack () => void optional Back button click handler
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
showBackButton boolean optional Show back button
Default: true
showMetadata boolean optional Show article metadata (date, type)
Default: true
className string optional Custom class name
flow HelpFlow optional The flow to display articles for (either pass flow object or flowSlug)
flowSlug string optional Flow slug to fetch (alternative to passing flow object)
onArticleClick (article: HelpArticle) => void optional Click handler for articles
onBack () => void optional Back button click handler
renderEmpty () => ReactNode optional Custom render function for empty state
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
showBackButton boolean optional Show back button
Default: true
showSearch boolean optional Show search input
Default: true
data HelpArticle[] page number per_page number total number total_pages number collection null | HelpCollection flows HelpFlow[] className string optional Custom class name
contactSupportUrl string optional Contact support URL
description string optional Page description
featuredArticles HelpArticle[] optional Featured articles to display on the main view
heading string optional Page heading
headingAlignment 'left' | 'center' | 'right' optional Heading alignment
Default: 'center'
onArticleClick (article: HelpArticle, flow: null | HelpFlow) => void optional External callback when article is clicked (for custom routing) If not provided, internal navigation is used
onFlowClick (flow: HelpFlow) => void optional External callback when flow is clicked (for custom routing) If not provided, internal navigation is used
onLiveChatClick () => void optional Live chat handler
quickActions QuickAction[] optional Quick action buttons to display
renderEmpty () => ReactNode optional Custom render function for empty state
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
showFooter boolean optional Show contact support footer
Default: true
showSearch boolean optional Show search input
Default: true
useExternalRouting boolean optional Use external routing instead of internal state management Set to true if you want to handle navigation yourself via onFlowClick/onArticleClick
Default: false
variant 'list' | 'grid' optional Layout variant for collections
Default: 'grid'
created_at string description null | string optional flows HelpFlow[] optional id string is_live boolean name string project_id string updated_at string version string className string optional Custom class name
contactSupportUrl string optional Contact support URL
description string optional Page description
featuredArticles HelpArticle[] optional Featured articles to display
heading string optional Page heading
headingAlignment 'left' | 'center' | 'right' optional Heading alignment
Default: 'center'
onArticleClick (article: HelpArticle, flow: HelpFlow) => void optional Click handler for articles
onFlowClick (flow: HelpFlow) => void optional Click handler for flows
onLiveChatClick () => void optional Live chat handler
quickActions QuickAction[] optional Quick action buttons to display
renderEmpty () => ReactNode optional Custom render function for empty state
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderFlow (flow: HelpFlow) => ReactNode optional Custom render function for flows
renderLoading () => ReactNode optional Custom render function for loading state
showFooter boolean optional Show contact support footer
Default: true
showSearch boolean optional Show search input
Default: true
variant 'list' | 'grid' optional Layout variant
Default: 'grid'
articles HelpArticle[] optional collection_id string color null | string optional created_at string description null | string optional display_type FlowDisplayType icon null | string optional id string name string slug string sort_order number updated_at string useHelpArticle Hook Fetches a single help article by slug.
articleSlug string The article slug to fetch
flowId string The flow ID the article belongs to
skip boolean optional Skip initial fetch
Default: false
article null | HelpArticle The article data
error null | string Error message if any
isLoading boolean Loading state
refetch () => Promise<void> Manually refetch data
skip boolean optional Skip initial fetch
Default: false
collection null | HelpCollection Help collection
error null | string Error message if any
flows HelpFlow[] Help flows
isLoading boolean Loading state
refetch () => Promise<void> Manually refetch data
useHelpFlow Hook Fetches a single help flow by slug.
flowSlug string The flow slug to fetch
skip boolean optional Skip initial fetch
Default: false
error null | string Error message if any
flow null | HelpFlow The flow data
isLoading boolean Loading state
refetch () => Promise<void> Manually refetch data
author_user_id string content string cover_image_url null | string optional created_at string excerpt null | string optional features ReleaseFeature[] optional id string is_published boolean items ReleaseItem[] optional labels string[] project_id string published_at null | string optional slug string title string updated_at string version null | string optional wish_ids string[] className string optional Custom class name
onClick () => void optional Click handler
release Release The release data
showCoverImage boolean optional Show cover image
Default: true
showDate boolean optional Show date
Default: true
showLabels boolean optional Show labels
Default: true
className string optional Custom class name
onBack () => void optional Back button click handler
release Release optional The release to display (either pass release object or releaseSlug)
releaseSlug string optional Release slug to fetch (alternative to passing release object)
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
showBackButton boolean optional Show back button
Default: true
description string id string image_url null | string optional release_id string sort_order number title string className string optional Custom class name
description string optional Page description
heading string optional Page heading
headingAlignment 'left' | 'center' | 'right' optional Heading alignment
Default: 'left'
limit number optional Maximum number of releases to show
Default: 50
onReleaseClick (release: Release) => void optional Click handler for releases
renderEmpty () => ReactNode optional Custom render function for empty state
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
renderRelease (release: Release, index: number) => ReactNode optional Custom render function for releases
variant 'cards' | 'compact' | 'timeline' optional Layout variant
Default: 'timeline'
className string optional Custom class name
description string optional Page description
heading string optional Page heading
headingAlignment 'left' | 'center' | 'right' optional Heading alignment
Default: 'left'
limit number optional Maximum number of releases to show
Default: 50
onReleaseClick (release: Release) => void optional External callback when release is clicked (for custom routing) If not provided, internal navigation is used
renderEmpty () => ReactNode optional Custom render function for empty state
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
useExternalRouting boolean optional Use external routing instead of internal state management Set to true if you want to handle navigation yourself via onReleaseClick
Default: false
variant 'cards' | 'compact' | 'timeline' optional Layout variant for list
Default: 'timeline'
data Release[] page number per_page number total number total_pages number useRelease Hook Fetches a single release by slug.
releaseSlug string The release slug to fetch
skip boolean optional Skip initial fetch
Default: false
error null | string Error message if any
isLoading boolean Loading state
refetch () => Promise<void> Manually refetch data
release null | Release The release data
limit number optional Maximum number of releases to fetch
Default: 50
skip boolean optional Skip initial fetch
Default: false
error null | string Error message if any
isLoading boolean Loading state
refetch () => Promise<void> Manually refetch data
releases Release[] List of releases
columns RoadmapColumn[] optional created_at string description null | string optional id string is_default boolean name string project_id string show_comments boolean show_vote_counts boolean updated_at string visibility RoadmapVisibility className string optional Custom class name
description string optional Page description
developersNote string optional Developer's note
heading string optional Page heading
headingAlignment 'left' | 'center' | 'right' optional Heading alignment
Default: 'left'
onItemClick (item: RoadmapItem) => void optional Click handler for items
refreshInterval number optional Auto-refresh interval in milliseconds
Default: 0
renderColumn (column: RoadmapColumn) => ReactNode optional Custom render function for columns
renderEmpty () => ReactNode optional Custom render function for empty state
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderItem (item: RoadmapItem) => ReactNode optional Custom render function for items
renderLoading () => ReactNode optional Custom render function for loading state
showComments boolean optional Show comment counts
Default: true
showVoteCounts boolean optional Show vote counts on items
Default: true
variant 'list' | 'kanban' | 'timeline' optional Layout variant
Default: 'kanban'
className string optional Custom class name
column RoadmapColumn The column data
onItemClick (item: RoadmapItem) => void optional Click handler for items
renderItem (item: RoadmapItem) => ReactNode optional Custom render function for items
showVoteCounts boolean optional Show vote counts on items
Default: true
color string created_at string id string items RoadmapItem[] optional name string roadmap_id string sort_order number updated_at string wip_limit null | number optional columns RoadmapColumn[] customization null | object optional roadmap null | Roadmap total_items number color null | string optional column_id string created_at string description null | string optional id string roadmap_id string sort_order number target_date null | string optional title string updated_at string wish null | Wish optional wish_id null | string optional refreshInterval number optional Auto-refresh interval in milliseconds (0 to disable)
Default: 0
skip boolean optional Skip initial fetch
Default: false
columns RoadmapColumn[] Roadmap columns with items
error null | string Error message if any
isLoading boolean Loading state
refetch () => Promise<void> Manually refetch data
roadmap null | Roadmap Roadmap data
totalItems number Total number of items
created_at string id string message string status IncidentStatus className string optional Custom class name
description string optional Page description
heading string optional Page heading
headingAlignment 'left' | 'center' | 'right' optional Heading alignment
Default: 'left'
maxPastIncidents number optional Max number of past incidents to show
Default: 5
onIncidentClick (incident: StatusIncident) => void optional Click handler for incidents
renderComponent (component: StatusComponent) => ReactNode optional Custom render for component
renderIncident (incident: StatusIncident) => ReactNode optional Custom render for incident
renderOverallStatus (status: OverallStatus) => ReactNode optional Custom render for overall status
showComponentDescriptions boolean optional Show component descriptions
Default: true
showIncidentHistory boolean optional Show incident history
Default: true
status StatusData Status data to display
description string optional group string optional id string name string status ComponentStatus components StatusComponent[] incidents StatusIncident[] last_updated string optional overall_status OverallStatus affected_components string[] optional created_at string id string impact IncidentImpact resolved_at null | string optional status IncidentStatus title string updates IncidentUpdate[] className string optional Custom class name
incident StatusIncident The incident to display
onBack () => void optional Back button click handler
showAffectedComponents boolean optional Show affected components
Default: true
showBackButton boolean optional Show back button
Default: true
created_at string description null | string id string is_active boolean name string project_id string slug string updated_at string active_count number active_updates StatusUpdate[] current_status StatusType recent_updates StatusUpdate[] resolved_count number services StatusPageService[] services_status Record<string, StatusType> status_breakdown Record<string, number> status_page StatusPage total_updates number color null | string created_at string description null | string group_name null | string id string is_active boolean name string sort_order number status_page_id string updated_at string affected_services string[] created_at string description string id string is_public boolean resolved_at null | string state StatusState status_page_id string status_type StatusType title string updated_at string enabled boolean optional Whether to fetch immediately
Default: true
refreshInterval number optional Auto-refresh interval in milliseconds (0 to disable)
Default: 30000
slug string optional Status page slug
Default: 'status'
error null | string Error message
isLoading boolean Loading state
overview null | StatusPageOverview Raw API overview response
refetch () => Promise<void> Manually refresh
status null | StatusData Transformed status data ready for StatusBoard
Waitlist status response
is_on_waitlist boolean Whether the user/email is on the waitlist
joined_at string optional When the user joined (if on waitlist)
position number optional Position in the waitlist (if available)
mime_type string optional name string size number url string accessToken string optional Access token for viewing tickets (from magic link)
checkDescription string optional Check status section description
checkTitle string optional Check status section title
className string optional Custom class name
customFormId string optional Custom contact form ID to use instead of default support form. When provided, fetches the form config and renders its fields dynamically. The form should have integration.type = 'support' to create tickets.
description string optional Page description
heading string optional Page heading
headingAlignment 'left' | 'center' | 'right' optional Heading alignment
Default: 'left'
onCheckStatus (email: string) => void optional Callback when checking status (optional - uses magic link by default)
onSubmitError (error: string) => void optional Callback when submission fails
onSubmitSuccess (ticket: SupportRequest) => void optional Callback when ticket is successfully submitted
onTicketClick (ticket: SupportRequest) => void optional Callback when a ticket is clicked
showAttachments boolean optional Show file attachments
Default: true
showCategory boolean optional Show category selector
Default: true
showCheckStatus boolean optional Show check status tab
Default: true
showName boolean optional Show name field
Default: true
submitButtonText string optional Submit button text
Default: 'Send Request'
submitDescription string optional Submit section description
submitTitle string optional Submit section title
attachments SupportAttachment[] optional author_email null | string optional author_name null | string optional author_type 'user' | 'team_member' author_user_id null | string optional content string created_at string id string is_internal boolean support_request_id string assignee_id null | string optional attachments SupportAttachment[] optional category null | SupportRequestCategory optional created_at string description string id string message_count number messages SupportMessage[] optional priority null | SupportRequestPriority optional project_id string resolved_at null | string optional status SupportRequestStatus subject string updated_at string user_email string user_name null | string optional attachments File[] optional category SupportRequestCategory optional description string external_user_id string optional subject string user_email string user_name string optional data SupportRequest[] page number per_page number total number total_pages number onSubmitError (error: string) => void optional Callback when a submission fails
onSubmitSuccess (ticket: SupportRequest) => void optional Callback when a ticket is successfully submitted
addMessage (ticketId: string, token: string, content: string) => Promise<null | object> Add a message to a ticket
clearMessages () => void Clear any error or success messages
error null | string Error message if any
getTicket (ticketId: string, token: string) => Promise<null | SupportRequest> Get a specific ticket by ID with token
isSendingMagicLink boolean Loading state for magic link request
isSubmitting boolean Loading state for ticket submission
isVerifying boolean Loading state for token verification
requestMagicLink (email: string) => Promise<boolean> Request a magic link to access tickets
submitTicket (data: SupportRequestInput) => Promise<null | SupportRequest> Submit a new support ticket
successMessage null | string Success message after submitting
verifyToken (token: string) => Promise<null | object> Verify a magic link token
API Response wrapper
data T optional error object optional success boolean baseUrl string orgSlug string optional projectId string projectSlug string optional apiUrl string optional Optional API URL override (defaults to https://api.appgram.dev)
enableFingerprinting boolean optional Enable browser fingerprinting for anonymous voting
Default: true
orgSlug string optional Organization slug (used for public URLs)
projectId string Your Appgram project ID
projectSlug string optional Project slug (used for public URLs)
theme AppgramTheme optional Theme customization
client AppgramClient The API client instance
config Required<Pick<AppgramConfig, 'projectId'>> & AppgramConfig The Appgram configuration
fingerprint null | string Browser fingerprint for anonymous voting
theme AppgramTheme Theme values
children ReactNode Child components
config AppgramConfig Appgram configuration
borderRadius number optional colors Partial<CustomColors> optional Light mode colors (used when mode is 'light' or system is light)
darkColors Partial<CustomColors> optional Dark mode colors (used when mode is 'dark' or system is dark) If not provided, will auto-generate from light colors
mode ThemeMode optional Theme mode - 'light', 'dark', or 'system' (default: 'system')
typography Partial<CustomTypography> optional className string optional Additional CSS classes
onClick (post: BlogPost) => void optional Called when the card is clicked
post BlogPost The blog post to display
variant 'default' | 'featured' | 'compact' optional Card variant
Default: 'default'
Blog/Resources Types
color null | string optional description null | string optional id string name string post_count number optional slug string category_slug string optional is_featured boolean optional page number optional per_page number optional search string optional tag string optional categories BlogCategory[] optional List of categories for filtering
className string optional Additional CSS classes
isLoading boolean optional Loading state
onCategoryChange (category: null | string) => void optional Called when a category is selected
onPageChange (page: number) => void optional Called when page changes
onPostClick (post: BlogPost) => void optional Called when a post is clicked
onSearchChange (query: string) => void optional Called when search query changes
page number optional Current page
posts BlogPost[] List of blog posts to display
renderEmpty () => ReactNode optional Custom empty state component
renderLoading () => ReactNode optional Custom loading component
searchQuery string optional Search query
selectedCategory null | string optional Currently selected category
showCategories boolean optional Show category filter
Default: true
showSearch boolean optional Show search input
Default: true
totalPages number optional Total pages
variant 'list' | 'grid' optional Grid variant
Default: 'grid'
author_name null | string optional category object optional category_id null | string optional content string created_at string excerpt null | string optional id string is_featured boolean meta_description null | string optional og_image_url null | string optional project_id string published_at string slug string tags string[] title string updated_at string view_count number className string optional Additional CSS classes
onBack () => void optional Back button click handler
onRelatedPostClick (post: BlogPost) => void optional Called when a related post is clicked
post BlogPost optional The blog post to display (either pass post object or postSlug)
postSlug string optional Post slug to fetch (alternative to passing post object)
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
showBackButton boolean optional Show back button
Default: true
showRelatedPosts boolean optional Show related posts section
Default: true
data BlogPost[] page number per_page number total number total_pages number className string optional Additional CSS classes
initialCategory string optional Initial category filter
initialSearch string optional Initial search query
onBackToList () => void optional Called when navigating back to list
onPostView (post: BlogPost) => void optional Called when a post is viewed
postsPerPage number optional Posts per page
Default: 9
renderEmpty () => ReactNode optional Custom render function for empty state
renderError (error: string, retry: () => void) => ReactNode optional Custom render function for error state
renderLoading () => ReactNode optional Custom render function for loading state
showCategories boolean optional Show category filter
Default: true
showRelatedPosts boolean optional Show related posts on detail view
Default: true
showSearch boolean optional Show search input
Default: true
variant 'list' | 'grid' optional Grid variant for list view
Default: 'grid'
color string description null | string optional icon null | string optional id string name string slug string wish_count number optional article_id string flow_id string optional flow_slug string optional similarity number slug string title string type 'help_article' | 'blog_post' optional Source type - determines routing behavior
accentColor string optional Accent color for the widget (used for links, send button, avatar accents)
Default: '#6366f1'
agentName string optional Name of the chat agent
Default: 'Help Assistant'
apiUrl string optional API URL for the help center
className string optional Custom class name
colors ChatWidgetColors optional Color customization options
fontSize string optional Base font size for the widget Can be 'sm' (12px), 'base' (14px), 'lg' (16px), or a custom value like '13px' or '0.875rem'
Default: 'base'
greeting string optional Initial greeting message
Default: 'Hello'
logoUrl string optional Logo URL for the agent avatar
onArticleClick (slug: string, source: ChatSource) => void optional Callback when an article source is clicked. Provides the article slug and full source data for flexible routing.
onSupportClick () => void optional Callback when support button is clicked
options ChatOption[] optional Quick reply options shown initially
projectId string Project ID for API calls
subtitle string optional Subtitle shown below greeting
Default: 'How can I help you today?'
author_avatar_url null | string optional author_name string author_type 'user' | 'anonymous' | 'team_member' author_user_id null | string optional content string created_at string id string is_deleted boolean is_official boolean parent_id null | string optional replies Comment[] optional reply_count number updated_at string wish_id string Comment Types
avatar_url null | string optional name string author_email string optional author_name string optional content string parent_id string optional wish_id string data Comment[] page number per_page number total number total_pages number createdAt string optional description string optional emailRecipient string emailSubject string enabled boolean fields ContactFormField[] id string integration ContactFormIntegration optional Integration settings for form submission
name string submitButtonText string successMessage string updatedAt string optional id string label string options string[] optional placeholder string optional required boolean type ContactFormFieldType validation ContactFormFieldValidation optional maxLength number optional minLength number optional pattern string optional className string optional Custom class name
description string optional Optional description override
formId string Form ID to load
onError (error: string) => void optional Called on submission error
onSuccess () => void optional Called when the form is submitted successfully
projectId string Project ID for submission
title string optional Optional title override
data Record<string, string | boolean> form_id string id string project_id string submitted_at string data Record<string, string | boolean> metadata Record<string, unknown> optional Customization & Theme Types
accent string background string border string optional cardBackground string optional cardText string optional info string optional infoSubtle string optional muted string optional mutedForeground string optional navbarBackground string optional navbarText string optional primary string secondary string success string optional successSubtle string optional text string warning string optional warningSubtle string optional fontFamily string optional fontSizes object optional borderRadius number optional cardStyle object optional Paginated response wrapper
data T[] page number per_page number total number total_pages number icon ComponentType<object> optional label string onClick () => void Survey
created_at string description string id string is_active boolean name string nodes SurveyNode[] optional number_of_questions number optional number_of_responses number optional project_id string responses SurveyResponse[] optional slug string updated_at string Survey Answer
answer boolean optional answer_options string[] optional answer_rating number optional answer_text string optional created_at string id string node object optional node_id string response_id string Survey Node Individual questions or result nodes in a survey decision tree.
answer_no_node_id null | string answer_yes_node_id null | string branches SurveyNodeBranch[] optional created_at string id string is_required boolean optional max_rating number optional min_rating number optional next_node_id null | string optional options SurveyNodeOption[] optional parent_id null | string question string question_type SurveyQuestionType result_message null | string sort_order number survey_id string updated_at string Survey Node Branch Conditional branching configuration for decision tree logic.
condition object next_node_id string Survey Node Option
label string value string className string optional Custom class name
description string optional Optional description override
externalUserId string optional External user ID to attach to the response
metadata Record<string, unknown> optional Additional metadata to attach to the response
onComplete () => void optional Called when the survey is submitted successfully
onError (error: string) => void optional Called on submission error
slug string Survey slug to load
title string optional Optional title override
Survey Response
answers SurveyAnswer[] optional created_at string external_user_id null | string fingerprint string id string metadata Record<string, unknown> survey_id string Input for submitting a survey response
answers object[] external_user_id string optional fingerprint string metadata Record<string, unknown> optional skip boolean optional Skip initial fetch
Default: false
categories BlogCategory[] List of blog categories
error null | string Error message if any
isLoading boolean Loading state
refetch () => Promise<void> Manually refetch data
skip boolean optional Skip initial fetch
Default: false
slug string The blog post slug to fetch
error null | string Error message if any
isLoading boolean Loading state
post null | BlogPost The blog post data
refetch () => Promise<void> Manually refetch data
relatedPosts BlogPost[] Related posts
category string optional Filter by category slug
featured boolean optional Only featured posts
per_page number optional Items per page
Default: 10
refreshInterval number optional Auto-refresh interval in milliseconds
search string optional Search query
skip boolean optional Skip initial fetch
Default: false
tag string optional Filter by tag
error null | string Error message if any
isLoading boolean Loading state
page number Current page number
posts BlogPost[] List of blog posts
refetch () => Promise<void> Manually refetch data
setFilters (filters: Partial<UseBlogPostsOptions>) => void Update filters
setPage (page: number) => void Set the current page
total number Total number of posts
totalPages number Total number of pages
perPage number optional Number of comments per page
Default: 20
skip boolean optional Skip initial fetch
Default: false
wishId string The wish ID to fetch comments for
comments Comment[] List of comments
createComment (data: Omit<CommentCreateInput, 'wish_id'>) => Promise<null | Comment> Create a new comment
error null | string Error message if any
isCreating boolean Loading state for creating a comment
isLoading boolean Loading state
nextPage () => void Go to next page
page number Current page
prevPage () => void Go to previous page
refetch () => Promise<void> Manually refetch data
setPage (page: number) => void Go to specific page
total number Total number of comments
totalPages number Total pages
enabled boolean optional Whether to fetch the form immediately
Default: true
trackView boolean optional Whether to track form views for analytics
Default: true
error null | string form null | ContactForm isLoading boolean refetch () => Promise<void> onError (error: string) => void optional onSuccess (submission: ContactFormSubmission) => void optional rateLimitMs number optional Rate limit cooldown in milliseconds
Default: 5000
clearMessages () => void error null | string isRateLimited boolean isSubmitting boolean submitForm (projectId: string, formId: string, data: ContactFormSubmitInput) => Promise<null | ContactFormSubmission> successMessage null | string validateField (value: string, field: object) => null | string skip boolean optional Skip initial fetch
Default: false
error null | string Error message if any
isLoading boolean Loading state
posts BlogPost[] List of featured blog posts
refetch () => Promise<void> Manually refetch data
enabled boolean optional Whether to fetch the survey immediately
Default: true
error null | string isLoading boolean nodes SurveyNode[] refetch () => Promise<void> survey null | Survey onError (error: string) => void optional onSuccess (response: SurveyResponse) => void optional clearMessages () => void error null | string isSubmitting boolean submitResponse (surveyId: string, data: SurveySubmitInput) => Promise<null | SurveyResponse> successMessage null | string email string optional Email to auto-check waitlist status for on mount
fetchCountOnMount boolean optional Whether to fetch the waitlist count on mount
Default: true
onJoinError (error: string) => void optional Callback when join fails
onJoinSuccess (entry: WaitlistEntry) => void optional Callback when successfully joined the waitlist
onLeaveError (error: string) => void optional Callback when leave fails
onLeaveSuccess () => void optional Callback when successfully left the waitlist
checkStatus (email: string) => Promise<null | WaitlistStatus> Check if an email is on the waitlist
clearMessages () => void Clear error and success messages
count null | number Total count of users on the waitlist
error null | string Error message if any operation failed
isCheckingStatus boolean Loading state for status check
isJoining boolean Loading state for join operation
isLeaving boolean Loading state for leave operation
isLoading boolean Loading state for initial data fetch
isOnWaitlist null | boolean Whether the provided email is on the waitlist
join (data: WaitlistJoinInput) => Promise<null | WaitlistEntry> Join the waitlist
leave (email: string) => Promise<boolean> Leave the waitlist
refreshCount () => Promise<void> Refresh the waitlist count
status null | WaitlistStatus Current user's waitlist status details
successMessage null | string Success message after successful operation
Waitlist count response
count number Total number of users on the waitlist
Waitlist entry (returned after joining)
created_at string When the user joined
email string Email address
id string Unique ID of the waitlist entry
name string optional Name (if provided)
position number optional Position in the waitlist
Input for joining a waitlist
email string Email address to add to waitlist
metadata Record<string, unknown> optional Optional additional metadata
name string optional Optional name of the user
autoPlayInterval number optional Auto-play carousel interval in ms (0 to disable)
Default: 5000
autoShow boolean optional Auto-show popup on mount if there's a new release Uses localStorage to track seen releases
Default: true
className string optional Custom class name
maxItems number optional Maximum number of items to show
Default: 5
onOpenChange (open: boolean) => void optional Callback when open state changes
onViewAll () => void optional Click handler for "View All" button
open boolean optional Whether the popup is open
position 'bottom-right' | 'bottom-left' | 'bottom-center' optional Position of the popup
Default: 'bottom-right'
showMedia boolean optional Show media carousel
Default: true
showTypes 'feature' | 'improvement' | 'bugfix' | 'other'[] optional Show only specific item types
storageKey string optional localStorage key for tracking seen releases
Default: 'appgram-seen-release'
title string optional Title for the popup
Default: "What's New"
Help Center Types
guidefaqtutorial operationaldegradedpartial_outagemajor_outage Contact Form Types Configurable contact forms for collecting user submissions.
textemailtextareaselectradiocheckbox listaccordiondecision_treewizard minormajorcritical investigatingidentifiedmonitoringresolved operationaldegradedpartial_outagemajor_outage publicprivatevoters_only activeresolved Status Page Types Types for status page API responses.
operationalmaintenancedegraded_performancepartial_outagemajor_outageincident bug_reportfeature_requestgeneral_inquirybillingaccount lowmediumhighcritical Support Types
newopenin_progressresolvedclosed Survey Question Types
yes_noshort_answerparagraphmultiple_choicecheckboxesrating Theme mode - 'light', 'dark', or 'system' (follows OS preference)
lightdarksystem lowmediumhighcritical Wish (Feature Request) Types
pendingunder_reviewplannedin_progresscompleteddeclined Merges Tailwind CSS classes with proper precedence handling
inputs ClassValue[] Class values to merge
string Merged class string
Get or create a fingerprint for the current browser/device
string The fingerprint string
Reset the stored fingerprint (for testing purposes)