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) {
- {() => }
+ {() => }
>
);