/** * @file Integration registry — metadata, official SVG logos, and SEO data for * every platform Pulse supports. * * ! SVG paths sourced from simple-icons (https://simpleicons.org). * ! All icons use a 24×24 viewBox. * * * 75 integrations across 7 categories. */ import { type ReactNode } from 'react' // * ─── Types ────────────────────────────────────────────────────────────────── export type IntegrationCategory = | 'framework' | 'backend' | 'ssg' | 'cms' | 'ecommerce' | 'platform' | 'hosting' export interface Integration { id: string name: string description: string category: IntegrationCategory /** Brand hex colour (with #) */ brandColor: string /** Whether the icon needs `dark:invert` (black-only logos) */ invertInDark?: boolean /** Official 24×24 SVG as a React node */ icon: ReactNode /** URL to official documentation / website */ officialUrl: string /** Related integration IDs for cross-linking */ relatedIds: string[] /** Whether this integration has a dedicated guide page */ dedicatedPage: boolean } // * ─── Category labels (for UI grouping) ────────────────────────────────────── export const categoryLabels: Record = { framework: 'JavaScript Frameworks', backend: 'Backend Frameworks', ssg: 'Static Sites & Documentation', cms: 'CMS & Blogging', ecommerce: 'eCommerce', platform: 'Platforms & Tools', hosting: 'Hosting & Deployment', } export const categoryOrder: IntegrationCategory[] = [ 'framework', 'backend', 'ssg', 'cms', 'ecommerce', 'platform', 'hosting', ] // * ─── Integration registry ────────────────────────────────────────────────── export const integrations: Integration[] = [ // * ─── JavaScript Frameworks ──────────────────────────────────────────────── { id: 'nextjs', name: 'Next.js', description: 'Add privacy-friendly analytics to your Next.js application using next/script.', category: 'framework', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://nextjs.org/docs', relatedIds: ['react', 'vercel', 'nuxt'], dedicatedPage: true, }, { id: 'react', name: 'React', description: 'Integrate Pulse with any React SPA (Create React App, Vite, etc).', category: 'framework', brandColor: '#61DAFB', icon: ( ), officialUrl: 'https://react.dev', relatedIds: ['nextjs', 'remix', 'gatsby', 'preact'], dedicatedPage: true, }, { id: 'vue', name: 'Vue.js', description: 'Simple setup for Vue 2 and Vue 3 applications.', category: 'framework', brandColor: '#4FC08D', icon: ( ), officialUrl: 'https://vuejs.org', relatedIds: ['nuxt', 'vitepress'], dedicatedPage: true, }, { id: 'angular', name: 'Angular', description: 'Add Pulse analytics to your Angular application with a simple script tag.', category: 'framework', brandColor: '#0F0F11', invertInDark: true, icon: ( ), officialUrl: 'https://angular.dev', relatedIds: ['react', 'vue'], dedicatedPage: true, }, { id: 'svelte', name: 'Svelte', description: 'Integrate Pulse with Svelte or SvelteKit in under a minute.', category: 'framework', brandColor: '#FF3E00', icon: ( ), officialUrl: 'https://svelte.dev', relatedIds: ['astro', 'vue'], dedicatedPage: true, }, { id: 'nuxt', name: 'Nuxt', description: 'Configure Pulse in your Nuxt application via nuxt.config.', category: 'framework', brandColor: '#00DC82', icon: ( ), officialUrl: 'https://nuxt.com/docs', relatedIds: ['vue', 'nextjs', 'vitepress'], dedicatedPage: true, }, { id: 'remix', name: 'Remix', description: 'Add Pulse to your Remix app via the root route loader.', category: 'framework', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://remix.run/docs', relatedIds: ['react', 'nextjs'], dedicatedPage: true, }, { id: 'astro', name: 'Astro', description: 'Integrate Pulse with your Astro site for lightning-fast analytics.', category: 'framework', brandColor: '#BC52EE', icon: ( ), officialUrl: 'https://docs.astro.build', relatedIds: ['svelte', 'hugo', 'eleventy'], dedicatedPage: true, }, { id: 'solidjs', name: 'Solid.js', description: 'Add Pulse analytics to your Solid.js application.', category: 'framework', brandColor: '#2C4F7C', icon: ( ), officialUrl: 'https://www.solidjs.com/docs', relatedIds: ['react', 'qwik', 'preact'], dedicatedPage: false, }, { id: 'qwik', name: 'Qwik', description: 'Integrate Pulse analytics with your Qwik application.', category: 'framework', brandColor: '#AC7EF4', icon: ( ), officialUrl: 'https://qwik.dev/docs', relatedIds: ['react', 'solidjs', 'astro'], dedicatedPage: false, }, { id: 'preact', name: 'Preact', description: 'Add Pulse analytics to your lightweight Preact application.', category: 'framework', brandColor: '#673AB8', icon: ( ), officialUrl: 'https://preactjs.com/guide', relatedIds: ['react', 'solidjs'], dedicatedPage: false, }, { id: 'htmx', name: 'HTMX', description: 'Add Pulse analytics to your HTMX-powered site.', category: 'framework', brandColor: '#3366CC', icon: ( ), officialUrl: 'https://htmx.org/docs', relatedIds: ['django', 'flask', 'laravel', 'rails'], dedicatedPage: false, }, { id: 'ember', name: 'Ember.js', description: 'Add Pulse analytics to your Ember.js application.', category: 'framework', brandColor: '#E04E39', icon: ( ), officialUrl: 'https://guides.emberjs.com', relatedIds: ['react', 'angular'], dedicatedPage: false, }, // * ─── Backend Frameworks ─────────────────────────────────────────────────── { id: 'laravel', name: 'Laravel', description: 'Add Pulse analytics to your Laravel app via Blade templates.', category: 'backend', brandColor: '#FF2D20', icon: ( ), officialUrl: 'https://laravel.com/docs', relatedIds: ['django', 'rails', 'wordpress'], dedicatedPage: true, }, { id: 'django', name: 'Django', description: 'Add Pulse analytics to your Django app via templates.', category: 'backend', brandColor: '#092E20', icon: ( ), officialUrl: 'https://docs.djangoproject.com', relatedIds: ['flask', 'laravel', 'htmx'], dedicatedPage: true, }, { id: 'rails', name: 'Ruby on Rails', description: 'Add Pulse analytics to your Rails app via ERB layouts.', category: 'backend', brandColor: '#D30001', icon: ( ), officialUrl: 'https://guides.rubyonrails.org', relatedIds: ['laravel', 'django', 'jekyll'], dedicatedPage: true, }, { id: 'flask', name: 'Flask', description: 'Add Pulse analytics to your Flask app via Jinja2 templates.', category: 'backend', brandColor: '#3BABC3', icon: ( ), officialUrl: 'https://flask.palletsprojects.com', relatedIds: ['django', 'htmx', 'express'], dedicatedPage: true, }, { id: 'express', name: 'Express', description: 'Serve Pulse analytics from your Express.js application.', category: 'backend', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://expressjs.com', relatedIds: ['flask', 'nextjs', 'react'], dedicatedPage: true, }, // * ─── Static Sites & Documentation ───────────────────────────────────────── { id: 'gatsby', name: 'Gatsby', description: 'Add Pulse to your Gatsby site via gatsby-ssr or a plugin.', category: 'ssg', brandColor: '#663399', icon: ( ), officialUrl: 'https://www.gatsbyjs.com/docs', relatedIds: ['react', 'nextjs', 'hugo'], dedicatedPage: true, }, { id: 'hugo', name: 'Hugo', description: 'Drop the Pulse script into your Hugo partial or base template.', category: 'ssg', brandColor: '#FF4088', icon: ( ), officialUrl: 'https://gohugo.io/documentation', relatedIds: ['jekyll', 'eleventy', 'astro'], dedicatedPage: true, }, { id: 'eleventy', name: 'Eleventy', description: 'Add Pulse analytics to your Eleventy (11ty) static site.', category: 'ssg', brandColor: '#222222', invertInDark: true, icon: ( ), officialUrl: 'https://www.11ty.dev/docs', relatedIds: ['hugo', 'jekyll', 'astro'], dedicatedPage: true, }, { id: 'jekyll', name: 'Jekyll', description: 'Add Pulse analytics to your Jekyll site via Liquid templates.', category: 'ssg', brandColor: '#CC0000', icon: ( ), officialUrl: 'https://jekyllrb.com/docs', relatedIds: ['hugo', 'eleventy', 'github-pages'], dedicatedPage: false, }, { id: 'docusaurus', name: 'Docusaurus', description: 'Add Pulse analytics to your Docusaurus documentation site.', category: 'ssg', brandColor: '#3ECC5F', icon: ( ), officialUrl: 'https://docusaurus.io/docs', relatedIds: ['vitepress', 'mkdocs', 'gatsby'], dedicatedPage: false, }, { id: 'vitepress', name: 'VitePress', description: 'Add Pulse analytics to your VitePress documentation site.', category: 'ssg', brandColor: '#5C73E7', icon: ( ), officialUrl: 'https://vitepress.dev', relatedIds: ['docusaurus', 'vue', 'nuxt'], dedicatedPage: false, }, { id: 'hexo', name: 'Hexo', description: 'Add Pulse analytics to your Hexo blog or documentation site.', category: 'ssg', brandColor: '#0E83CD', icon: ( ), officialUrl: 'https://hexo.io/docs', relatedIds: ['hugo', 'jekyll', 'eleventy'], dedicatedPage: false, }, { id: 'mkdocs', name: 'MkDocs', description: 'Add Pulse analytics to your MkDocs documentation site.', category: 'ssg', brandColor: '#526CFE', icon: ( ), officialUrl: 'https://www.mkdocs.org', relatedIds: ['docusaurus', 'vitepress', 'django'], dedicatedPage: false, }, // * ─── CMS & Blogging ────────────────────────────────────────────────────── { id: 'wordpress', name: 'WordPress', description: 'Add the tracking script to your WordPress header or use a plugin.', category: 'cms', brandColor: '#21759B', icon: ( ), officialUrl: 'https://wordpress.org/documentation', relatedIds: ['ghost', 'drupal', 'woocommerce'], dedicatedPage: true, }, { id: 'ghost', name: 'Ghost', description: 'Inject Pulse into your Ghost theme via Code Injection settings.', category: 'cms', brandColor: '#15171A', invertInDark: true, icon: ( ), officialUrl: 'https://ghost.org/docs', relatedIds: ['wordpress', 'blogger'], dedicatedPage: true, }, { id: 'drupal', name: 'Drupal', description: 'Add Pulse analytics to your Drupal site using a module or theme.', category: 'cms', brandColor: '#0678BE', icon: ( ), officialUrl: 'https://www.drupal.org/docs', relatedIds: ['wordpress', 'joomla'], dedicatedPage: true, }, { id: 'joomla', name: 'Joomla', description: 'Add Pulse analytics to your Joomla site via template or extension.', category: 'cms', brandColor: '#5091CD', icon: ( ), officialUrl: 'https://docs.joomla.org', relatedIds: ['wordpress', 'drupal'], dedicatedPage: false, }, { id: 'strapi', name: 'Strapi', description: 'Add Pulse analytics to your Strapi-powered frontend.', category: 'cms', brandColor: '#4945FF', icon: ( ), officialUrl: 'https://docs.strapi.io', relatedIds: ['contentful', 'sanity', 'nextjs'], dedicatedPage: false, }, { id: 'sanity', name: 'Sanity', description: 'Add Pulse analytics to your Sanity-powered frontend.', category: 'cms', brandColor: '#0D0E12', invertInDark: true, icon: ( ), officialUrl: 'https://www.sanity.io/docs', relatedIds: ['strapi', 'contentful', 'nextjs'], dedicatedPage: false, }, { id: 'contentful', name: 'Contentful', description: 'Add Pulse analytics to your Contentful-powered frontend.', category: 'cms', brandColor: '#2478CC', icon: ( ), officialUrl: 'https://www.contentful.com/developers/docs', relatedIds: ['strapi', 'sanity', 'nextjs'], dedicatedPage: false, }, { id: 'payload', name: 'Payload CMS', description: 'Add Pulse analytics to your Payload CMS frontend.', category: 'cms', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://payloadcms.com/docs', relatedIds: ['strapi', 'contentful', 'nextjs'], dedicatedPage: false, }, // * ─── eCommerce ──────────────────────────────────────────────────────────── { id: 'shopify', name: 'Shopify', description: 'Add privacy-first analytics to your Shopify store via theme editor.', category: 'ecommerce', brandColor: '#7AB55C', icon: ( ), officialUrl: 'https://shopify.dev/docs', relatedIds: ['woocommerce', 'bigcommerce', 'prestashop'], dedicatedPage: true, }, { id: 'woocommerce', name: 'WooCommerce', description: 'Add Pulse analytics to your WooCommerce store.', category: 'ecommerce', brandColor: '#96588A', icon: ( ), officialUrl: 'https://woocommerce.com/documentation', relatedIds: ['shopify', 'wordpress', 'bigcommerce'], dedicatedPage: false, }, { id: 'bigcommerce', name: 'BigCommerce', description: 'Add Pulse analytics to your BigCommerce store.', category: 'ecommerce', brandColor: '#121118', invertInDark: true, icon: ( ), officialUrl: 'https://developer.bigcommerce.com/docs', relatedIds: ['shopify', 'woocommerce', 'prestashop'], dedicatedPage: false, }, { id: 'prestashop', name: 'PrestaShop', description: 'Add Pulse analytics to your PrestaShop store.', category: 'ecommerce', brandColor: '#DF0067', icon: ( ), officialUrl: 'https://devdocs.prestashop-project.org', relatedIds: ['shopify', 'woocommerce', 'bigcommerce'], dedicatedPage: false, }, // * ─── Platforms & Tools ──────────────────────────────────────────────────── { id: 'webflow', name: 'Webflow', description: 'Paste the Pulse snippet into your Webflow project custom code.', category: 'platform', brandColor: '#146EF5', icon: ( ), officialUrl: 'https://university.webflow.com', relatedIds: ['squarespace', 'wix', 'framer'], dedicatedPage: true, }, { id: 'squarespace', name: 'Squarespace', description: 'Add Pulse to Squarespace via the Code Injection panel.', category: 'platform', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://support.squarespace.com', relatedIds: ['webflow', 'wix', 'carrd'], dedicatedPage: true, }, { id: 'wix', name: 'Wix', description: 'Add Pulse to your Wix site via the Custom Code settings.', category: 'platform', brandColor: '#0C6EFC', icon: ( ), officialUrl: 'https://support.wix.com', relatedIds: ['webflow', 'squarespace', 'framer'], dedicatedPage: true, }, { id: 'framer', name: 'Framer', description: 'Add Pulse analytics to your Framer site via custom code.', category: 'platform', brandColor: '#0055FF', icon: ( ), officialUrl: 'https://www.framer.com/help', relatedIds: ['webflow', 'squarespace', 'wix'], dedicatedPage: true, }, { id: 'carrd', name: 'Carrd', description: 'Add Pulse analytics to your Carrd one-page site.', category: 'platform', brandColor: '#596CAF', icon: ( ), officialUrl: 'https://carrd.co/docs', relatedIds: ['framer', 'webflow'], dedicatedPage: false, }, { id: 'blogger', name: 'Blogger', description: 'Add Pulse analytics to your Blogger blog.', category: 'platform', brandColor: '#FF5722', icon: ( ), officialUrl: 'https://support.google.com/blogger', relatedIds: ['wordpress', 'ghost'], dedicatedPage: false, }, { id: 'gtm', name: 'Google Tag Manager', description: 'Add Pulse analytics via Google Tag Manager.', category: 'platform', brandColor: '#246FDB', icon: ( ), officialUrl: 'https://tagmanager.google.com', relatedIds: ['wordpress', 'shopify', 'webflow'], dedicatedPage: true, }, { id: 'notion', name: 'Notion', description: 'Add Pulse analytics to Notion-powered websites.', category: 'platform', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://www.notion.so', relatedIds: ['webflow', 'framer', 'carrd'], dedicatedPage: false, }, // * ─── Hosting & Deployment ───────────────────────────────────────────────── { id: 'cloudflare-pages', name: 'Cloudflare Pages', description: 'Deploy with Pulse analytics on Cloudflare Pages.', category: 'hosting', brandColor: '#F38020', icon: ( ), officialUrl: 'https://developers.cloudflare.com/pages', relatedIds: ['netlify', 'vercel', 'github-pages'], dedicatedPage: false, }, { id: 'netlify', name: 'Netlify', description: 'Add Pulse analytics to sites deployed on Netlify.', category: 'hosting', brandColor: '#00C7B7', icon: ( ), officialUrl: 'https://docs.netlify.com', relatedIds: ['cloudflare-pages', 'vercel', 'github-pages'], dedicatedPage: false, }, { id: 'vercel', name: 'Vercel', description: 'Add Pulse analytics to sites deployed on Vercel.', category: 'hosting', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://vercel.com/docs', relatedIds: ['netlify', 'cloudflare-pages', 'nextjs'], dedicatedPage: false, }, { id: 'github-pages', name: 'GitHub Pages', description: 'Add Pulse analytics to your GitHub Pages site.', category: 'hosting', brandColor: '#222222', invertInDark: true, icon: ( ), officialUrl: 'https://docs.github.com/en/pages', relatedIds: ['jekyll', 'hugo', 'netlify'], dedicatedPage: false, }, // * ─── CMS & Blogging (continued) ────────────────────────────────────────── { id: 'craftcms', name: 'Craft CMS', description: 'Add Pulse to your Craft CMS site with a simple template tag.', category: 'cms', brandColor: '#E5422B', icon: ( ), officialUrl: 'https://craftcms.com/docs', relatedIds: ['wordpress', 'statamic', 'drupal'], dedicatedPage: false, }, { id: 'statamic', name: 'Statamic', description: 'Integrate Pulse with your Statamic site via Antlers templates.', category: 'cms', brandColor: '#FF269E', icon: ( ), officialUrl: 'https://statamic.dev/docs', relatedIds: ['craftcms', 'laravel', 'wordpress'], dedicatedPage: false, }, { id: 'typo3', name: 'TYPO3', description: 'Add Pulse to your TYPO3 site via TypoScript or Fluid templates.', category: 'cms', brandColor: '#FF8700', icon: ( ), officialUrl: 'https://docs.typo3.org', relatedIds: ['wordpress', 'drupal', 'joomla'], dedicatedPage: false, }, { id: 'kirby', name: 'Kirby', description: 'Add Pulse to your Kirby site via PHP snippets.', category: 'cms', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://getkirby.com/docs', relatedIds: ['craftcms', 'statamic', 'grav'], dedicatedPage: false, }, { id: 'grav', name: 'Grav', description: 'Add Pulse to your Grav site via Twig templates.', category: 'cms', brandColor: '#221E1F', invertInDark: true, icon: ( ), officialUrl: 'https://learn.getgrav.org', relatedIds: ['kirby', 'craftcms', 'hugo'], dedicatedPage: false, }, { id: 'umbraco', name: 'Umbraco', description: 'Add Pulse to your Umbraco site via Razor views.', category: 'cms', brandColor: '#3544B1', icon: ( ), officialUrl: 'https://docs.umbraco.com', relatedIds: ['wordpress', 'drupal', 'typo3'], dedicatedPage: false, }, { id: 'storyblok', name: 'Storyblok', description: 'Add Pulse to the frontend of your Storyblok-powered site.', category: 'cms', brandColor: '#09B3AF', icon: ( ), officialUrl: 'https://www.storyblok.com/docs', relatedIds: ['contentful', 'prismic', 'nextjs'], dedicatedPage: false, }, { id: 'prismic', name: 'Prismic', description: 'Add Pulse to the frontend of your Prismic-powered site.', category: 'cms', brandColor: '#5163BA', icon: ( ), officialUrl: 'https://prismic.io/docs', relatedIds: ['contentful', 'storyblok', 'nextjs'], dedicatedPage: false, }, // * ─── eCommerce (continued) ─────────────────────────────────────────────── { id: 'shopware', name: 'Shopware', description: 'Add Pulse analytics to your Shopware 6 store.', category: 'ecommerce', brandColor: '#189EFF', icon: ( ), officialUrl: 'https://developer.shopware.com/docs', relatedIds: ['shopify', 'woocommerce', 'magento'], dedicatedPage: false, }, { id: 'magento', name: 'Magento', description: 'Add Pulse analytics to your Magento / Adobe Commerce store.', category: 'ecommerce', brandColor: '#F46F25', icon: ( ), officialUrl: 'https://developer.adobe.com/commerce', relatedIds: ['shopify', 'woocommerce', 'shopware'], dedicatedPage: false, }, // * ─── Platforms & Tools (continued) ─────────────────────────────────────── { id: 'bubble', name: 'Bubble', description: 'Add Pulse to your Bubble no-code application.', category: 'platform', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://manual.bubble.io', relatedIds: ['webflow', 'framer', 'wix'], dedicatedPage: false, }, { id: 'discourse', name: 'Discourse', description: 'Add Pulse to your Discourse community forum.', category: 'platform', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://meta.discourse.org/docs', relatedIds: ['wordpress', 'ghost'], dedicatedPage: false, }, { id: 'hubspot', name: 'HubSpot', description: 'Add Pulse to your HubSpot-hosted pages.', category: 'platform', brandColor: '#FF7A59', icon: ( ), officialUrl: 'https://knowledge.hubspot.com', relatedIds: ['wordpress', 'webflow'], dedicatedPage: false, }, { id: 'substack', name: 'Substack', description: 'Add Pulse to your Substack publication with a custom domain.', category: 'platform', brandColor: '#FF6719', icon: ( ), officialUrl: 'https://substack.com', relatedIds: ['ghost', 'blogger', 'wordpress'], dedicatedPage: false, }, { id: 'linktree', name: 'Linktree', description: 'Add Pulse to your Linktree page via custom code.', category: 'platform', brandColor: '#43E55E', icon: ( ), officialUrl: 'https://linktr.ee', relatedIds: ['carrd', 'framer', 'webflow'], dedicatedPage: false, }, { id: 'weebly', name: 'Weebly', description: 'Add Pulse to your Weebly site via header code.', category: 'platform', brandColor: '#2C5CC5', icon: ( ), officialUrl: 'https://www.weebly.com', relatedIds: ['squarespace', 'wix', 'webflow'], dedicatedPage: false, }, // * ─── Static Sites & Documentation (continued) ─────────────────────────── { id: 'gitbook', name: 'GitBook', description: 'Add Pulse to your GitBook documentation site.', category: 'ssg', brandColor: '#BBDDE5', icon: ( ), officialUrl: 'https://docs.gitbook.com', relatedIds: ['docusaurus', 'readme', 'readthedocs'], dedicatedPage: false, }, { id: 'gridsome', name: 'Gridsome', description: 'Add Pulse to your Gridsome static site.', category: 'ssg', brandColor: '#00A672', icon: ( ), officialUrl: 'https://gridsome.org/docs', relatedIds: ['gatsby', 'vue', 'nuxt'], dedicatedPage: false, }, { id: 'readthedocs', name: 'Read the Docs', description: 'Add Pulse to your Read the Docs documentation.', category: 'ssg', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://docs.readthedocs.io', relatedIds: ['sphinx', 'mkdocs', 'docusaurus'], dedicatedPage: false, }, { id: 'sphinx', name: 'Sphinx', description: 'Add Pulse to your Sphinx documentation via conf.py.', category: 'ssg', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://www.sphinx-doc.org', relatedIds: ['readthedocs', 'mkdocs', 'docusaurus'], dedicatedPage: false, }, { id: 'readme', name: 'ReadMe', description: 'Add Pulse to your ReadMe API documentation.', category: 'ssg', brandColor: '#018EF5', icon: ( ), officialUrl: 'https://docs.readme.com', relatedIds: ['gitbook', 'docusaurus', 'readthedocs'], dedicatedPage: false, }, // * ─── JavaScript Frameworks (continued) ─────────────────────────────────── { id: 'flutter', name: 'Flutter', description: 'Add Pulse to your Flutter web application.', category: 'framework', brandColor: '#02569B', icon: ( ), officialUrl: 'https://docs.flutter.dev', relatedIds: ['react', 'angular', 'preact'], dedicatedPage: false, }, // * ─── Hosting & Deployment (continued) ──────────────────────────────────── { id: 'render', name: 'Render', description: 'Deploy with Pulse analytics on Render.', category: 'hosting', brandColor: '#000000', invertInDark: true, icon: ( ), officialUrl: 'https://docs.render.com', relatedIds: ['netlify', 'vercel', 'cloudflare-pages'], dedicatedPage: false, }, { id: 'firebase', name: 'Firebase Hosting', description: 'Deploy with Pulse analytics on Firebase Hosting.', category: 'hosting', brandColor: '#DD2C00', icon: ( ), officialUrl: 'https://firebase.google.com/docs/hosting', relatedIds: ['netlify', 'vercel', 'render'], dedicatedPage: false, }, // * ─── Platforms & Tools (continued) ─────────────────────────────────────── { id: 'amp', name: 'Google AMP', description: 'Add Pulse to your AMP (Accelerated Mobile Pages) site.', category: 'platform', brandColor: '#005AF0', icon: ( ), officialUrl: 'https://amp.dev/documentation', relatedIds: ['gtm', 'wordpress', 'webflow'], dedicatedPage: false, }, ] // * ─── Helpers ──────────────────────────────────────────────────────────────── /** Retrieve a single integration by its route slug. */ export function getIntegration(id: string): Integration | undefined { return integrations.find((i) => i.id === id) } /** Group integrations by category, preserving category ordering. */ export function getGroupedIntegrations(): { category: IntegrationCategory label: string items: Integration[] }[] { return categoryOrder .map((cat) => ({ category: cat, label: categoryLabels[cat], items: integrations.filter((i) => i.category === cat), })) .filter((group) => group.items.length > 0) }