Skip to content

freshworks-developers/superstack

Repository files navigation

superstack

superstack

App that covers React + FDK capabilities on Platform 3.0
(Freshdesk + Freshservice)

Platform 3.0 FDK 10.1.0 Node.js 24.11.0 React 19.2.4 Tailwind CSS 3.4.1 Material UI 5.15.12 Crayons 4.2.0 Redux Toolkit 2.2.1 Freshworks-only License


Superstack ships working examples of every major Freshworks platform capability so you can clone, explore, and start building immediately.

What's included:

  • 13 Freshdesk placeholder locations + minimal service_ticket.ticket_sidebar (Freshservice install stub); modal and dialog templates
  • 37 request templates (Freshdesk CRUD, optional cross-product ticket templates fs* / fd* for API Playground, mailboxes, email settings, external APIs)
  • Server Method Invocation (SMI) with two server functions; Instance communication demo on full page (instance.get / send / receive on the same Freshdesk page)
  • 7 event handlers (app lifecycle, ticket, contact, conversation)
  • Custom React-based installation parameters page
  • Redux state management, React Router, i18n (6 languages), Error Boundary
  • Jest test suite with coverage

Table of Contents

Getting started

Prerequisites Quick Start Development Commands

Project & UI surface

Project Structure Frontend Stack Placeholders

Platform & integrations

Request Templates Server Functions (SMI) Event Handlers
Instance Communication Interface Methods Data Storage
Installation Parameters App Lifecycle

Quality, legal & reference

Testing Contributing License Resources

Prerequisites

This app targets Freshworks Platform 3.0 (generated by FDK). Node.js and FDK versions expected for this repo are pinned in manifest.json under engines.

Requirement Version
Node.js 24.11.0 (engines.node in manifest.json)
npm 10.x or higher (ships with Node.js 24)
FDK (Freshworks Developer Kit) 10.1.0 (engines.fdk in manifest.json)

Quick Start

1. Install FDK

npm install https://cdn.freshdev.io/fdk/latest-v24.tgz -g

Verify:

fdk version

2. Clone and install

git clone https://github.com/freshworks-developers/superstack.git
cd superstack
npm install

3. Run locally

fdk run

The local dev server starts at http://*:10001/ (open http://localhost:10001 on your machine). Leave this process running while you test in the browser.

When fdk run is up, the CLI reminds you to append dev=true to your Freshdesk URL and points at helper URLs (installation page and event simulation).

3.5 Subscribe to modules (system settings)

Before dev=true binds local assets, tell the FDK which Freshdesk modules you use and your account URL.

  1. With fdk run running, open http://localhost:10001/system_settings in your browser.
  2. Subscribe to the modules you plan to test:
    • common — full-page app, CTI global sidebar, shared requests, SMI, events.
    • support_ticket — ticket sidebar, top navigation, attachment, conversation editor, backgrounds, etc.
    • support_contact — contact sidebar and background.
    • support_company — company background.
  3. Enter Organization domain and Enter account URL using your Freshdesk login URL (e.g. https://yourcompany.freshdesk.com).
  4. Click Continue. Complete http://localhost:10001/custom_configs / iparams if prompted (§4.1).

Reopen http://localhost:10001/system_settings if you change which surfaces you test.

Instance APIs in local dev: client.instance.get() only lists app instances that are active in the same browser tab (e.g. full page app open in Apps plus ticket sidebar on a ticket). Use Home → Instance communication after opening both surfaces with dev=true.

4. Test in Freshdesk

Use a Freshdesk account where you can install or sideload the app. Complete §3.5 Subscribe to modules with your Freshdesk URL and support_ticket / common as needed, then follow the steps below so installation parameters, request templates, and server methods run against a real product context (not just unit tests).

4.1 Configure installation parameters (domain / API key)

Request templates and many samples need your Freshdesk domain and API key from the installation parameters UI.

  1. With fdk run running, open the local installation page:
    http://localhost:10001/custom_configs
    
  2. Enter valid values (same as you would in the live app settings) and save so the dev app can call the Freshdesk API.

Alternatively, complete the install / settings flow inside Freshdesk once the app is in dev mode; the iparams page is the React surface under config/.

4.2 Attach the local app to your Freshdesk session

Add dev=true to whatever Freshdesk URL you already have open:

  • No query string yet — start the query with ?dev=true (works for a bare portal URL with no path after the domain, or for any path that does not already include ?):

    https://yourcompany.freshdesk.com?dev=true
    https://yourcompany.freshdesk.com/a/tickets/1?dev=true
    
  • URL already has ?… — append with &dev=true (do not add a second ?):

    https://yourcompany.freshdesk.com/a/tickets/1?filter=new&openTicketSidebar=true&dev=true
    

After this, placeholders load from your machine at port 10001 instead of a published package.

4.3 Open the right surface for each feature

Where What to exercise
Freshdesk · Apps (full page app) Home: SMI (client.request.invoke), interface methods, data storage, app lifecycle demos. API Playground: Freshdesk templates, optional Cross-product (Freshservice) (fsGetTickets, fsCreateTicket, …) when Freshservice iparams are set, and external APIs.
Freshservice · Apps (full page app) Same Home demos. API Playground: templates that use current_host for Freshservice where applicable, optional Cross-product (Freshdesk) (fdGetTickets, fdCreateTicket, …) when Freshdesk iparams are set, plus external APIs.
Freshdesk · Any ticket Sidebar: SMI button (invokeFromClient), ticket-scoped UI. Top navigation, attachment, conversation editor, requester info, new-ticket requester info, background: additional invokeTemplate / platform examples.
Freshdesk · CTI global sidebar Ticket list-style invokeTemplate calls (e.g. get/create ticket).
Freshdesk · Any contact Contact sidebar and background placeholders.
Freshdesk · Any company Company sidebar and background placeholders.

Work through ticket and full page surfaces first if you are validating Freshdesk REST usage via templates; use Home → SMI and ticket sidebar → Call Server Method to verify serverless / SMI paths. For instance communication, open Apps (full page) and a ticket (sidebar) with dev=true, then use Home → Instance communication (send/receive between instances on the same page).

4.4 Simulate events (optional)

To trigger product, app setup, and external events without performing every action in the UI:

http://localhost:10001/web/test

Use this alongside real pages to confirm event handlers and lifecycle callbacks behave as expected.

4.5 Optional local helper URLs

URL Purpose
http://localhost:10001/system_settings Modules + Freshdesk account URL (if dev=true does not attach)
http://localhost:10001/custom_configs Installation parameters while developing
http://localhost:10001/web/test Simulate serverless / product events

4.6 Which manifest modules do I need?

No — you do not have to enable every module in system settings for every test run. On Freshdesk, select common plus the support_* modules you use. On Freshservice, select common and service_ticket (minimum for this repo to install there — see below).

5. Freshservice: full page app (minimum)

full_page_app lives under modules.common (same index.html as Freshdesk). Freshservice still needs at least one service_ticket placeholder for the app to install — this manifest uses ticket_sidebar mapped to ticketSidebarService.html (minimal copy only; the ticket sidebar surface is not reliable on Freshservice).

  1. fdk run, then http://localhost:10001/system_settings: subscribe common and service_ticket, enter your Freshservice account URL (https://yourorg.freshservice.com), ITSM or MSP if asked, Continue, then save custom_configs / iparams if prompted.
  2. Chrome: allow insecure content for your Freshservice origin so http://localhost:10001 can load in the iframe (Freshservice local testing).
  3. Append ?dev=true or &dev=true to your Freshservice URL, open Apps in the product menu — you should see the full-page Superstack UI (index.html).
  4. API Playground → Cross-product (Freshdesk) lists, fetches, and creates Freshdesk tickets via iparam.freshdeskDomain + iparam.freshdeskApi (optional pair on the installation page), mirroring fs* on Freshdesk.
  5. Use full page for the full Freshservice demo; ticketSidebarService.html exists to satisfy service_ticket only (not a Freshdesk-style sidebar experience).

Project Structure

superstack/
├── app/                              # Frontend
│   ├── index.html                    # Full Page App entry
│   ├── ticketSidebar.html            # Freshdesk ticket sidebar (support_ticket)
│   ├── ticketSidebarService.html     # Minimal Freshservice service_ticket.ticket_sidebar
│   ├── contactSidebar.html           # Contact Sidebar entry
│   ├── topNavigation.html            # Ticket Top Navigation entry
│   ├── ctiGlobalSidebar.html         # CTI Global Sidebar entry
│   ├── ticketBackground.html         # Ticket Background (no UI)
│   ├── timeEntryBackground.html      # Time Entry Background (no UI)
│   ├── contactBackground.html        # Contact Background (no UI)
│   ├── companyBackground.html        # Company Background (no UI)
│   ├── ticketAttachment.html         # Ticket Attachment entry
│   ├── ticketConversationEditor.html # Conversation Editor entry
│   ├── ticketRequesterInfo.html      # Requester Info entry
│   ├── newTicketRequesterInfo.html   # New Ticket Requester Info entry
│   ├── companySidebar.html           # Company Sidebar entry
│   ├── modal.html                    # Modal template
│   ├── dialog.html                   # Dialog template
│   ├── icon.svg                      # App icon
│   │
│   ├── components/                   # React components
│   │   ├── index.jsx                 # Entry point with Redux Provider
│   │   ├── App.jsx                   # Main app with React Router
│   │   ├── Home.jsx                  # Platform features demo
│   │   ├── ApiDemo.jsx               # Request Templates playground
│   │   ├── Counter.jsx               # Redux example
│   │   ├── Form.jsx                  # Crayons form + DB operations
│   │   ├── StockMarket.jsx           # Live data example
│   │   ├── TailwindPage.jsx          # Tailwind CSS demo
│   │   ├── MaterialuiAccordian.jsx   # Material UI example
│   │   ├── I18nPage.jsx              # Internationalization demo
│   │   ├── Modal.jsx                 # Modal component
│   │   ├── ClassComponent.jsx        # Class component example
│   │   ├── ErrorBoundary.jsx         # Error boundary wrapper
│   │   ├── context/                  # React Context providers
│   │   └── placeholders/             # Placeholder-specific components
│   │       ├── PlaceholderWrapper.jsx # Reusable init wrapper
│   │       ├── ticketSidebar.jsx     # Freshdesk ticket sidebar
│   │       ├── ticketSidebarService.jsx # Freshservice minimal ticket_sidebar
│   │       ├── topNavigation.jsx
│   │       ├── ctiGlobalSidebar.jsx
│   │       ├── contactSidebar.jsx
│   │       ├── companySidebar.jsx
│   │       ├── ticketBackground.jsx
│   │       ├── timeEntryBackground.jsx
│   │       ├── ticketAttachment.jsx
│   │       ├── ticketConversationEditor.jsx
│   │       ├── ticketRequesterInfo.jsx
│   │       └── newTicketRequesterInfo.jsx
│   │
│   ├── hooks/                        # Custom React hooks
│   │   └── useFreshworksData.js      # Freshworks data fetching hook
│   ├── reducer/                      # Redux reducers
│   │   ├── counterReducer.js
│   │   └── ticketsReducer.js
│   ├── store/                        # Redux store
│   │   └── index.js
│   ├── context/                      # i18n context
│   │   └── I18nContext.jsx
│   ├── i18n.js                       # Translation utility
│   ├── locales/                      # Translation files
│   │   ├── en.json
│   │   ├── es.json
│   │   ├── fr.json
│   │   ├── de.json
│   │   ├── ja.json
│   │   └── ar.json
│   ├── styles/
│   │   └── style.css
│   ├── icons/
│   │   └── image-one.svg
│   └── public/                       # Static assets
│       ├── banner.svg
│       └── logos/
│
├── config/                           # App configuration
│   ├── iparams.html                  # Custom iparam UI entry
│   ├── requests.json                 # Request template definitions
│   └── assets/
│       ├── components/
│       │   ├── main.jsx              # Iparam React entry
│       │   └── Iparam.jsx            # Iparam React component
│       └── style/
│           └── styles.css
│
├── server/                           # Server-side code
│   └── server.js                     # SMI functions + event handlers
│
├── tests/                            # Jest test suite
│   ├── App.test.js
│   ├── hooks/
│   │   └── useFreshworksData.test.js
│   └── reducers/
│       ├── counterReducer.test.js
│       └── ticketsReducer.test.js
│
├── manifest.json                     # Platform 3.0 manifest
├── package.json                      # Dependencies (npm)
├── jest.config.json                  # Jest configuration
├── tailwind.config.js                # Tailwind CSS configuration
├── postcss.config.js                 # PostCSS configuration
├── setupTests.js                     # Jest setup
└── LICENSE.md                        # Freshworks-only License

Placeholders

Placeholders define where your app renders. Superstack includes 13 Freshdesk location entries in manifest.json plus service_ticket.ticket_sidebar on ticketSidebarService.html (minimal stub for Freshservice install). common (full page, CTI) applies to both products when the app is installed there.

Placeholder Module HTML Entry Description
full_page_app common index.html Full page in the Apps menu
cti_global_sidebar common ctiGlobalSidebar.html Global CTI sidebar
ticket_top_navigation support_ticket topNavigation.html Top bar on ticket views
ticket_sidebar support_ticket ticketSidebar.html Freshdesk ticket sidebar (full demo)
ticket_sidebar service_ticket ticketSidebarService.html Freshservice install stub (full UI: full page)
ticket_requester_info support_ticket ticketRequesterInfo.html Requester info section
new_ticket_requester_info support_ticket newTicketRequesterInfo.html New ticket requester info
ticket_attachment support_ticket ticketAttachment.html Attachment section
ticket_conversation_editor support_ticket ticketConversationEditor.html Reply editor area
ticket_background support_ticket ticketBackground.html Background (no UI)
time_entry_background support_ticket timeEntryBackground.html Time Logs tab background
contact_sidebar support_contact contactSidebar.html Contact detail sidebar
contact_background support_contact contactBackground.html Contact page background
company_background support_company companyBackground.html Company page background
Modal / Dialog Interface modal.html, dialog.html Triggered programmatically

Freshdesk placeholders

Most templates target Freshdesk (current_host.endpoint_urls.freshdesk). Optional fs* templates call Freshservice using iparam.freshserviceDomain and iparam.freshserviceApi (see Cross-product (Freshservice) below). Optional fd* templates call Freshdesk using iparam.freshdeskDomain and iparam.freshdeskApi while the app runs on Freshservice (see Cross-product (Freshdesk)).


Request Templates

Request templates are defined in config/requests.json and declared in manifest.json under modules.common.requests. They proxy HTTP calls through the platform so credentials never reach the browser.

Cross-product (Freshservice) from the Freshdesk full-page app

These are not client.instance messages. They are separate HTTPS request templates to the Freshservice API while the app runs in Freshdesk:

Template Method Purpose
fsGetTickets GET List tickets on the Freshservice account in iparams
fsGetTicketById GET Get one Freshservice ticket
fsCreateTicket POST Create a Freshservice ticket

Configure Freshservice domain + API key on the installation page (optional pair). Use API Playground → Cross-product (Freshservice) to try them.

Cross-product (Freshdesk) from the Freshservice full-page app

Symmetric fd* templates call the Freshdesk API using installation params only (no reliance on current_host.endpoint_urls.freshdesk):

Template Method Purpose
fdGetTickets GET List tickets on the Freshdesk account in iparams
fdGetTicketById GET Get one Freshdesk ticket
fdCreateTicket POST Create a Freshdesk ticket

Configure Freshdesk domain + API key on the installation page (optional pair). Use API Playground → Cross-product (Freshdesk) to try them.

Freshdesk API Templates

Template Method Endpoint
getTickets GET /api/v2/tickets
getTicketById GET /api/v2/tickets/{id}
searchTickets GET /api/v2/search/tickets
createTicket POST /api/v2/tickets
updateTicket PUT /api/v2/tickets/{id}
deleteTicket DELETE /api/v2/tickets/{id}
getContacts GET /api/v2/contacts
getContactById GET /api/v2/contacts/{id}
searchContacts GET /api/v2/search/contacts
createContact POST /api/v2/contacts
updateContact PUT /api/v2/contacts/{id}
deleteContact DELETE /api/v2/contacts/{id}
getCompanies GET /api/v2/companies
getCompanyById GET /api/v2/companies/{id}
searchCompanies GET /api/v2/search/companies
createCompany POST /api/v2/companies
updateCompany PUT /api/v2/companies/{id}
deleteCompany DELETE /api/v2/companies/{id}
getMailboxes GET /api/v2/email/mailboxes
getMailboxById GET /api/v2/email/mailboxes/{id}
createMailbox POST /api/v2/email/mailboxes
updateMailbox PUT /api/v2/email/mailboxes/{id}
deleteMailbox DELETE /api/v2/email/mailboxes/{id}
getEmailSettings GET /api/v2/email/settings
updateEmailSettings PUT /api/v2/email/settings
getEmailBcc GET /api/v2/notifications/email/bcc
updateEmailBcc PUT /api/v2/notifications/email/bcc
secureApiCall GET Custom domain + path

External API Templates

Template Method Host
getJoke GET icanhazdadjoke.com
getProgrammingJoke GET official-joke-api.appspot.com
getChuckNorrisJoke GET api.chucknorris.io
getRandomUser GET randomuser.me
getWeatherByCity GET api.openweathermap.org

Usage

// Frontend: invoke a template at runtime
const response = await client.request.invokeTemplate("getTickets", {
  context: { per_page: "10", page: "1" }
});
const tickets = JSON.parse(response.response);

Request Templates Documentation


Server Functions (SMI)

Server Method Invocation lets the frontend call server-side functions securely. Defined in server/server.js and declared in manifest.json under modules.common.functions.

Function Timeout Purpose
invokeFromClient 15s Generic server call from frontend
serverMethod 10s Action-based dispatch (sync, analyze, etc.)
// Frontend: call a server function
const result = await client.request.invoke("invokeFromClient", {
  action: "test",
  ticketId: 123
});

Server Method Invocation Documentation


Event Handlers

Server-side handlers that fire automatically on Freshdesk events. Defined in server/server.js and declared in manifest.json under each module's events.

Event Module Handler Trigger
onAppInstall common onAppInstallCallback App installed
onAppUninstall common onAppUninstallCallback App uninstalled
onTicketCreate support_ticket onTicketCreateCallback Ticket created
onTicketUpdate support_ticket onTicketUpdateCallback Ticket updated
onConversationCreate support_ticket onConversationCreateCallback Reply or note added
onContactCreate support_contact onContactCreateCallback Contact created
onContactUpdate support_contact onContactUpdateCallback Contact updated

Events Documentation


Instance Communication

When your app runs in multiple placeholders simultaneously, instances can talk to each other.

// Get all running instances
const instances = await client.instance.get();

// Send data to a specific instance
await client.instance.send({
  message: { action: "refresh" },
  receiver: [targetInstanceId]
});

// Listen for messages
client.instance.receive((event) => {
  const data = event.helper.getData();
});
Method Description
client.instance.get() List all active app instances
client.instance.context() Get current instance context
client.instance.send({ message, receiver }) Send data to other instances
client.instance.receive(callback) Listen for incoming messages
client.instance.resize({ height }) Resize current instance (max 700px)
client.instance.close() Close modal or dialog

Instance method

Instance communication

client.instance.get(), send(), and receive() coordinate multiple app instances on the same Freshdesk page (e.g. full page app + ticket sidebar + modals). instance.get() only sees iframes active in that browser tab.

Local dev: Open Apps (full page) and a ticket (sidebar), both with dev=true. Then use Home → Instance communication (refresh list, send to selected, receive log).

Different browser tabs do not share one instance list — that is expected platform behaviour, not specific to fdk run.


Interface Methods

Trigger UI actions from code.

// Notification
client.interface.trigger("showNotify", { type: "success", message: "Done!" });

// Modal
client.interface.trigger("showModal", {
  title: "Details",
  template: "modal.html",
  data: { ticketId: 123 }
});

// Dialog
client.interface.trigger("showDialog", { title: "Info", template: "dialog.html" });

// Confirmation
const result = await client.interface.trigger("showConfirm", {
  title: "Confirm",
  message: "Are you sure?"
});

// Set ticket field
client.interface.trigger("setValue", { id: "priority", value: 2 });

// Navigate to ticket
client.interface.trigger("click", { id: "ticket", value: 123 });

Interface Methods Documentation


Data Storage

The platform provides a key-value store (up to 6 MB per key).

await client.db.set("config", { theme: "dark" });
const result = await client.db.get("config");
await client.db.delete("config");

Data Storage Documentation


Installation Parameters

Superstack uses a custom React-based installation parameters page instead of JSON configuration.

config/
├── iparams.html             # Entry point loaded by FDK
└── assets/
    └── components/
        ├── main.jsx          # React mount
        └── Iparam.jsx        # Custom form component

The Iparam.jsx component renders the settings form. FDK calls postConfigs() to collect values and validate() before saving.

// Access iparams in frontend
const iparams = await client.iparams.get();

// Access in server event handler
function onAppInstallCallback(payload) {
  const domain = payload.iparams.freshdeskDomain;
}

Installation Parameters Documentation


App Lifecycle

const client = await app.initialized();

client.events.on("app.activated", () => {
  // App is visible -- fetch data here
});

client.events.on("app.deactivated", () => {
  // App is hidden -- clean up here
});

App Lifecycle Documentation


Frontend Stack

Dependency ranges are declared in package.json; the versions below are the minimum each range allows (^).

Library Version (package.json) Role
React 19.2.4 (react, react-dom) UI framework
Redux Toolkit 2.2.1 (@reduxjs/toolkit) State management
React Router 6.22.3 (react-router-dom) Client-side routing
Tailwind CSS 3.4.1 (tailwindcss) Utility-first CSS
Material UI 5.15.12 (@mui/material, @mui/icons-material) Component library
Freshworks Crayons 4.2.0 (@freshworks/crayons) Freshworks design system
date-fns 3.3.1 Date formatting

Testing

Automated (Jest)

Tests live in tests/ and use Jest 29.7.0 with jsdom (see devDependencies in package.json).

npm test

Test files:

File Covers
tests/App.test.js App component rendering
tests/reducers/counterReducer.test.js Counter Redux reducer
tests/reducers/ticketsReducer.test.js Tickets Redux reducer
tests/hooks/useFreshworksData.test.js Freshworks data hook

Manual (fdk run + Freshdesk or Freshservice)

End-to-end checks for request templates, SMI, instance / interface APIs, and installation parameters require a running dev server and dev=true. See §4 Test in Freshdesk and §5 Freshservice (full page).


Development Commands

Command Description
fdk run Start the local dev server
fdk validate Validate app structure and lint
fdk pack Package app for marketplace submission
npm test Run the Jest test suite
npm test -- --coverage Run tests with coverage report
npm run sync:readme Refresh version badges and tables from manifest.json + package.json

Contributing

Contributions are welcome. Please follow these steps:

  1. Fork the repository.
  2. Create a branch for your feature or fix:
    git checkout -b feat/my-feature
  3. Make your changes. Keep commits focused and descriptive.
  4. Validate before pushing:
    fdk validate
    npm test
  5. Push and open a Pull Request against main.

Guidelines

  • After bumping manifest.json engines or package.json dependencies, run npm run sync:readme.
  • Run fdk validate and ensure 0 platform errors and 0 lint errors before submitting.
  • All new features should include tests.
  • Use Conventional Commits for commit messages (feat:, fix:, docs:, chore:).
  • Keep PRs small and focused on a single change.
  • Do not commit node_modules/, .fdk/, log/, or coverage/.

Reporting Issues

Open an issue with:

  • A clear title and description.
  • Steps to reproduce.
  • Expected vs actual behavior.
  • FDK version (fdk version) and Node.js version (node -v).

License

This project is proprietary and licensed for Freshworks-product usage only. See LICENSE.md for terms and restrictions.


Resources

Topic Link
Freshworks Developer Portal developers.freshworks.com
Platform 3.0 SDK Docs SDK Documentation
Freshdesk API Reference developers.freshdesk.com/api
Freshworks Crayons crayons.freshworks.com
Developer Community community.freshworks.dev
FDK CLI Reference CLI Documentation

Built for the Freshworks Developer Community

About

Superstack is a Platform 3.0 Freshworks app showcasing React + FDK capabilities with production-ready examples, templates, and tooling to help you build, test, and ship faster across Freshdesk and Freshservice.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors