diff --git a/docusaurus.config.js b/docusaurus.config.js index 715796c316..37625fb90f 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -35,10 +35,10 @@ if ('${process.env.MIXPANEL_PROJECT_TOKEN}' && '${process.env.MIXPANEL_PROJECT_T if (isPlayPage) { window.mixpanel.track('Play Page Viewed', viwedPayload); } - + window.document.addEventListener('click', function (event) { var target = event.target; - + // Check if the clicked element is a link with an href attribute if (target.tagName === 'A' && target.hasAttribute('href')) { if (window.mixpanel) { @@ -50,7 +50,7 @@ if ('${process.env.MIXPANEL_PROJECT_TOKEN}' && '${process.env.MIXPANEL_PROJECT_T window.mixpanel.track('Link clicked', payload); const isPlay = payload.href.includes('play.flow.com'); if (isPlay) { - window.mixpanel.track('Play Link clicked', payload); + window.mixpanel.track('Play Link clicked', payload); } } } @@ -246,14 +246,27 @@ const config = { image: 'img/og-image-flow-docs-2025-dark.png', metadata: [ { name: 'twitter:card', content: 'summary_large_image' }, - { name: 'twitter:image', content: getUrl() + '/img/og-image-flow-docs-2025-dark.png' }, - { property: 'og:image', content: getUrl() + '/img/og-image-flow-docs-2025-dark.png' }, + { + name: 'twitter:image', + content: getUrl() + '/img/og-image-flow-docs-2025-dark.png', + }, + { + property: 'og:image', + content: getUrl() + '/img/og-image-flow-docs-2025-dark.png', + }, { property: 'og:image:type', content: 'image/png' }, { property: 'og:image:width', content: '1200' }, { property: 'og:image:height', content: '630' }, { property: 'og:type', content: 'website' }, - { property: 'og:description', content: 'Flow Developer Documentation - The future of culture and digital assets is built on Flow' }, - { property: 'og:logo', content: getUrl() + '/img/flow-docs-logo-light.png' }, + { + property: 'og:description', + content: + 'Flow Developer Documentation - The future of culture and digital assets is built on Flow', + }, + { + property: 'og:logo', + content: getUrl() + '/img/flow-docs-logo-light.png', + }, ], docs: { sidebar: { @@ -322,7 +335,7 @@ const config = { to: '/blockchain-development-tutorials/cadence/getting-started/smart-contract-interaction', }, { - label: "Tools & SDKs", + label: 'Tools & SDKs', to: '/build/tools', }, { @@ -514,7 +527,11 @@ const config = { rule.test?.toString() === '/\\.svg$/i' ) { for (const nestedRule of rule.oneOf || []) { - if (nestedRule && typeof nestedRule === 'object' && nestedRule.use instanceof Array) { + if ( + nestedRule && + typeof nestedRule === 'object' && + nestedRule.use instanceof Array + ) { for (const loader of nestedRule.use) { if ( typeof loader === 'object' && @@ -608,6 +625,7 @@ const config = { customFields: { flowNetwork, walletConnectProjectId, + cookbookApiKey: process.env.COOKBOOK_API_KEY, }, // Move deprecated markdown config to new location @@ -616,7 +634,7 @@ const config = { onBrokenMarkdownLinks: 'throw', }, }, - + // Enable partial Docusaurus Faster (keep webpack bundler for redocusaurus) future: { v4: true, @@ -631,4 +649,4 @@ const config = { }, }; -module.exports = config; \ No newline at end of file +module.exports = config; diff --git a/src/components/LazyDocsbot.js b/src/components/LazyDocsbot.js new file mode 100644 index 0000000000..dee46c9644 --- /dev/null +++ b/src/components/LazyDocsbot.js @@ -0,0 +1,34 @@ +import React, { lazy, Suspense, useState, useEffect } from 'react'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; + +const AskCookbook = lazy(() => import('@cookbookdev/docsbot/react')); + +export default function LazyDocsbot() { + const { siteConfig } = useDocusaurusContext(); + const [shouldLoad, setShouldLoad] = useState(false); + + useEffect(() => { + const load = () => { + if ('requestIdleCallback' in window) { + requestIdleCallback(() => setShouldLoad(true)); + } else { + setTimeout(() => setShouldLoad(true), 1); + } + }; + + if (document.readyState === 'complete') { + load(); + } else { + window.addEventListener('load', load); + return () => window.removeEventListener('load', load); + } + }, []); + + if (!shouldLoad) return null; + + return ( + + + + ); +} diff --git a/src/theme/SearchBar.js b/src/theme/SearchBar.js index b820e2654d..2a2fd5139a 100644 --- a/src/theme/SearchBar.js +++ b/src/theme/SearchBar.js @@ -1,17 +1,16 @@ import React from 'react'; import SearchBar from '@theme-original/SearchBar'; -import AskCookbook from '@cookbookdev/docsbot/react'; +import LazyDocsbot from '@site/src/components/LazyDocsbot'; import BrowserOnly from '@docusaurus/BrowserOnly'; import { event } from '@site/src/utils/gtags.client'; import { GA_EVENTS, GA_CATEGORIES } from '@site/src/constants/ga-events'; -/** It's a public API key, so it's safe to expose it here */ -const COOKBOOK_PUBLIC_API_KEY = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NzEyYWRkYjk5YjBmNWViM2ZkODQxOGMiLCJpYXQiOjE3MjkyNzc0MDMsImV4cCI6MjA0NDg1MzQwM30._bhlmAnFpvxvkTV0PvU-6FwabhFOdSOx-qed2UIogpY'; + export default function SearchBarWrapper(props) { const handleSearchClick = () => { // Check if we're on the homepage - const isHomepage = typeof window !== 'undefined' && window.location.pathname === '/'; - + const isHomepage = + typeof window !== 'undefined' && window.location.pathname === '/'; + // Track the search bar click event({ action: isHomepage ? GA_EVENTS.ACTION_CARD_CLICK : GA_EVENTS.SEARCH_CLICK, @@ -27,7 +26,7 @@ export default function SearchBarWrapper(props) { - {() => } + {() => } );