From 8a18cbf14c3003423d4e7dd3a246ad55efd8603f Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 27 Jul 2026 14:13:14 +0000 Subject: [PATCH 1/7] feat: replace APIs dropdown with API, SDK, and CLI links The navbar dropdown pointed at individual client, SDK, and CLI doc sets, including five GitHub links for the experimental clients. Point the navbar at the three landing pages instead, and list every experimental client on the API landing page so those libraries stay discoverable. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016as7phod6GN5z2g7x6ng1V --- apify-docs-theme/src/config.js | 92 ++++------------ docusaurus.config.js | 1 + src/pages/api/index.tsx | 187 +++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 71 deletions(-) diff --git a/apify-docs-theme/src/config.js b/apify-docs-theme/src/config.js index 32657657d1..7519774c49 100644 --- a/apify-docs-theme/src/config.js +++ b/apify-docs-theme/src/config.js @@ -84,78 +84,28 @@ const themeConfig = { rel: 'dofollow', }, { - label: 'APIs, SDKs & CLI', - type: 'dropdown', - activeBaseRegex: '^/(api|sdk|cli)/', + label: 'API', + href: `${absoluteUrl}/api`, + activeBasePath: 'api', position: 'right', - items: [ - { - label: 'API Reference', - href: `${absoluteUrl}/api/v2`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'SDK for JavaScript', - href: `${absoluteUrl}/sdk/js/docs/overview`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'SDK for Python', - href: `${absoluteUrl}/sdk/python/docs/overview`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'Client for JavaScript', - href: `${absoluteUrl}/api/client/js/docs`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'Client for Python', - href: `${absoluteUrl}/api/client/python/docs`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'CLI', - href: `${absoluteUrl}/cli/docs`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'Experimental client for Rust', - href: `https://github.com/apify/apify-client-rust`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'Experimental client for Go', - href: `https://github.com/apify/apify-client-go`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'Experimental client for PHP', - href: `https://github.com/apify/apify-client-php`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'Experimental client for Java', - href: `https://github.com/apify/apify-client-java`, - target: '_self', - rel: 'dofollow', - }, - { - label: 'Experimental client for .NET', - href: `https://github.com/apify/apify-client-dotnet`, - target: '_self', - rel: 'dofollow', - }, - ], + target: '_self', + rel: 'dofollow', + }, + { + label: 'SDK', + href: `${absoluteUrl}/sdk`, + activeBasePath: 'sdk', + position: 'right', + target: '_self', + rel: 'dofollow', + }, + { + label: 'CLI', + href: `${absoluteUrl}/cli`, + activeBasePath: 'cli', + position: 'right', + target: '_self', + rel: 'dofollow', }, ], }, diff --git a/docusaurus.config.js b/docusaurus.config.js index f23b9ccef9..46e424ad24 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -433,6 +433,7 @@ module.exports = { 'go', 'csharp', 'powershell', + 'rust', 'dart', 'objectivec', 'ocaml', diff --git a/src/pages/api/index.tsx b/src/pages/api/index.tsx index 55b62af000..e0f0395211 100644 --- a/src/pages/api/index.tsx +++ b/src/pages/api/index.tsx @@ -106,6 +106,150 @@ const BlogImageWrapper = styled.img` height: 100%; `; +interface ExperimentalClient { + language: string; + description: string; + repository: string; + installLanguage: string; + installSnippet: string; + exampleLanguage: string; + exampleSnippet: string; +} + +const experimentalClients: ExperimentalClient[] = [ + { + language: 'Rust', + description: 'Async client for Tokio-based Rust applications, built on reqwest.', + repository: 'https://github.com/apify/apify-client-rust', + installLanguage: 'bash', + installSnippet: `cargo add apify-client serde_json +cargo add tokio --features macros,rt-multi-thread`, + exampleLanguage: 'rust', + exampleSnippet: `use apify_client::ApifyClient; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = ApifyClient::new("MY-APIFY-TOKEN"); + + // Starts an Actor and waits for it to finish. + let run = client + .actor("john-doe/my-cool-actor") + .call::(None, Default::default(), None) + .await?; + + // Fetches results from the Actor's dataset. + let dataset_id = run.default_dataset_id.expect("run has a default dataset"); + let items = client + .dataset(&dataset_id) + .list_items::(Default::default()) + .await?; + println!("Got {} items", items.items.len()); + + Ok(()) +}`, + }, + { + language: 'Go', + description: 'Client for Go 1.23 or newer, built almost entirely on the standard library.', + repository: 'https://github.com/apify/apify-client-go', + installLanguage: 'bash', + installSnippet: 'go get github.com/apify/apify-client-go', + exampleLanguage: 'go', + exampleSnippet: `package main + +import ( + "context" + "fmt" + "log" + + apify "github.com/apify/apify-client-go" +) + +func main() { + client := apify.NewClient(apify.WithToken("MY-APIFY-TOKEN")) + ctx := context.Background() + + // Starts an Actor and waits for it to finish. + run, err := client.Actor("john-doe/my-cool-actor").Call(ctx, nil, apify.ActorStartOptions{}, nil) + if err != nil { + log.Fatal(err) + } + + // Fetches results from the Actor's dataset. + page, err := client.Dataset(run.DefaultDatasetID).ListItems(ctx, apify.DatasetListItemsOptions{}) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Got %d items\\n", page.Total) +}`, + }, + { + language: 'PHP', + description: 'Client for PHP 8.1 or newer, with Guzzle as the default HTTP transport.', + repository: 'https://github.com/apify/apify-client-php', + installLanguage: 'bash', + installSnippet: 'composer require apify/apify-client', + exampleLanguage: 'php', + exampleSnippet: `actor('john-doe/my-cool-actor')->call(null, null, null); + +// Fetches results from the Actor's dataset. +$items = $client->dataset((string) $run->getDefaultDatasetId())->listItems(); +echo 'Got ' . $items->getCount() . ' items' . PHP_EOL;`, + }, + { + language: 'Java', + description: 'Client for Java 17 or newer, published to Maven Central. Every call returns a CompletableFuture.', + repository: 'https://github.com/apify/apify-client-java', + installLanguage: 'xml', + installSnippet: ` + + com.apify + apify-client + 0.5.0 +`, + exampleLanguage: 'java', + exampleSnippet: `import com.apify.client.ApifyClient; +import com.apify.client.actor.ActorStartOptions; +import com.apify.client.dataset.DatasetListItemsOptions; +import com.apify.client.run.ActorRun; + +ApifyClient client = ApifyClient.create("MY-APIFY-TOKEN"); + +// Starts an Actor and waits for it to finish. +ActorRun run = client.actor("john-doe/my-cool-actor").call(null, new ActorStartOptions(), 120L).join(); + +// Fetches results from the Actor's dataset. +var items = client.dataset(run.getDefaultDatasetId()).listItems(new DatasetListItemsOptions()).join(); +System.out.println("Got " + items.getCount() + " items");`, + }, + { + language: '.NET', + description: 'Client for .NET 8.0 or newer, with cancellation-aware asynchronous calls.', + repository: 'https://github.com/apify/apify-client-dotnet', + installLanguage: 'bash', + installSnippet: 'dotnet add package Apify.Client', + exampleLanguage: 'csharp', + exampleSnippet: `using System; +using Apify.Client; + +var client = new ApifyClient("MY-APIFY-TOKEN"); + +// Starts an Actor and waits for it to finish. +var run = await client.Actor("john-doe/my-cool-actor").CallAsync(null, null, null); + +// Fetches results from the Actor's dataset. +var items = await client.Dataset(run.DefaultDatasetId!).ListItemsAsync(); +Console.WriteLine($"Got {items.Count} items");`, + }, +]; + export default function Api() { return ( @@ -278,6 +422,49 @@ dataset_items = apify_client.dataset(actor_call['defaultDatasetId']).list_items( ]} /> +
+ ({ + title: client.language, + content: ( + + {client.description} + +
+ + + View reference + +
+ + } + > + + {client.installSnippet} + {client.exampleSnippet} + +
+ ), + }))} + /> +
From 78f0428a0616c70693a04d9d07e4c3613d1fe599 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 28 Jul 2026 12:19:52 +0000 Subject: [PATCH 2/7] feat: add MCP nav item and restore API, SDK, and CLI dropdowns API, SDK, and CLI keep their dropdowns, which open on hover as before. Their labels now carry a link target, so clicking one opens the section landing page instead of only toggling the menu, and MCP joins them as a plain link. Resolve the active class in NavbarNavLink for absolute hrefs: Link drops isActive and activeClassName for those, so activeBaseRegex had no effect and the dropdown label only highlighted on an exact child-page match. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016as7phod6GN5z2g7x6ng1V --- apify-docs-theme/src/config.js | 78 ++++++++++++++++++- .../src/theme/NavbarItem/NavbarNavLink.jsx | 21 +++-- 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/apify-docs-theme/src/config.js b/apify-docs-theme/src/config.js index 7519774c49..9a1aa77393 100644 --- a/apify-docs-theme/src/config.js +++ b/apify-docs-theme/src/config.js @@ -83,26 +83,98 @@ const themeConfig = { target: '_self', rel: 'dofollow', }, + // The dropdown labels below carry both `href` and `to` on purpose. `href` keeps the + // target absolute, so the link resolves from the client, SDK, and CLI docs sites as + // well. `to` tells the Docusaurus dropdown that the label is a real link, so clicking + // it opens the landing page instead of only toggling the menu open. { label: 'API', + type: 'dropdown', href: `${absoluteUrl}/api`, - activeBasePath: 'api', + to: `${absoluteUrl}/api`, + activeBaseRegex: '^/api(/|$)', position: 'right', target: '_self', rel: 'dofollow', + items: [ + { + label: 'API reference', + href: `${absoluteUrl}/api/v2`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'Client for JavaScript', + href: `${absoluteUrl}/api/client/js/docs`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'Client for Python', + href: `${absoluteUrl}/api/client/python/docs`, + target: '_self', + rel: 'dofollow', + }, + ], }, { label: 'SDK', + type: 'dropdown', href: `${absoluteUrl}/sdk`, - activeBasePath: 'sdk', + to: `${absoluteUrl}/sdk`, + activeBaseRegex: '^/sdk(/|$)', position: 'right', target: '_self', rel: 'dofollow', + items: [ + { + label: 'SDK for JavaScript', + href: `${absoluteUrl}/sdk/js/docs/overview`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'SDK for Python', + href: `${absoluteUrl}/sdk/python/docs/overview`, + target: '_self', + rel: 'dofollow', + }, + ], }, { label: 'CLI', + type: 'dropdown', href: `${absoluteUrl}/cli`, - activeBasePath: 'cli', + to: `${absoluteUrl}/cli`, + activeBaseRegex: '^/cli(/|$)', + position: 'right', + target: '_self', + rel: 'dofollow', + items: [ + { + label: 'Installation', + href: `${absoluteUrl}/cli/docs/installation`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'Quick start', + href: `${absoluteUrl}/cli/docs/quick-start`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'Command reference', + href: `${absoluteUrl}/cli/docs/reference`, + target: '_self', + rel: 'dofollow', + }, + ], + }, + { + label: 'MCP', + href: `${absoluteUrl}/integrations/mcp`, + activeBasePath: 'integrations/mcp', position: 'right', target: '_self', rel: 'dofollow', diff --git a/apify-docs-theme/src/theme/NavbarItem/NavbarNavLink.jsx b/apify-docs-theme/src/theme/NavbarItem/NavbarNavLink.jsx index 2296239802..23c95dab4a 100644 --- a/apify-docs-theme/src/theme/NavbarItem/NavbarNavLink.jsx +++ b/apify-docs-theme/src/theme/NavbarItem/NavbarNavLink.jsx @@ -6,11 +6,14 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import { usePluginData } from '@docusaurus/useGlobalData'; import IconExternalLink from '@theme/Icon/ExternalLink'; +import clsx from 'clsx'; import React from 'react'; export default function NavbarNavLink({ activeBasePath, activeBaseRegex, + activeClassName = 'navbar__link--active', + className, to, href, label, @@ -30,7 +33,6 @@ export default function NavbarNavLink({ // TODO all this seems hacky // {to: 'version'} should probably be forbidden, in favor of {to: '/version'} const toUrl = useBaseUrl(to); - const activeBaseUrl = useBaseUrl(activeBasePath); const normalizedHref = useBaseUrl(href, { forcePrependBaseUrl: true }); const { siteConfig } = useDocusaurusContext(); const isInternalUrl = (url) => { @@ -63,16 +65,18 @@ export default function NavbarNavLink({ .some((item) => (item.to || item.href).endsWith(location.pathname)); if (href) { + // `Link` drops `isActive`/`activeClassName` for absolute URLs (they only work with the + // React Router link), so the active class has to be resolved here instead. + const isActive = + (activeBaseRegex && isRegexpStringMatch(activeBaseRegex, location.pathname)) || + (activeBasePath && location.pathname.startsWith(`/${activeBasePath}`)) || + dropDownHasActiveItem; + return ( ); @@ -82,13 +86,14 @@ export default function NavbarNavLink({ activeBaseRegex ? isRegexpStringMatch(activeBaseRegex, location.pathname) || dropDownHasActiveItem : location.pathname.startsWith(`/${activeBasePath}`), - activeClassName: 'navbar__link--active', + activeClassName, })} {...props} {...linkContentProps} From 86cfab8ff2b1dcaab3fa4c824c5acec281b8c28d Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 28 Jul 2026 12:41:34 +0000 Subject: [PATCH 3/7] feat: list every API client in the API navbar dropdown Restore the Rust, Go, PHP, Java, and .NET client links that the old dropdown carried, labeled the same way as the JavaScript and Python entries. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016as7phod6GN5z2g7x6ng1V --- apify-docs-theme/src/config.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/apify-docs-theme/src/config.js b/apify-docs-theme/src/config.js index 9a1aa77393..e9c34f4ece 100644 --- a/apify-docs-theme/src/config.js +++ b/apify-docs-theme/src/config.js @@ -115,6 +115,36 @@ const themeConfig = { target: '_self', rel: 'dofollow', }, + { + label: 'Client for Rust', + href: `https://github.com/apify/apify-client-rust`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'Client for Go', + href: `https://github.com/apify/apify-client-go`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'Client for PHP', + href: `https://github.com/apify/apify-client-php`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'Client for Java', + href: `https://github.com/apify/apify-client-java`, + target: '_self', + rel: 'dofollow', + }, + { + label: 'Client for .NET', + href: `https://github.com/apify/apify-client-dotnet`, + target: '_self', + rel: 'dofollow', + }, ], }, { From 686d2c320dbadcacd89eb80d1118eff2e52dda8b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 28 Jul 2026 13:01:41 +0000 Subject: [PATCH 4/7] docs: reorder experimental clients and drop their star buttons Move Rust to the end of the tab list, and remove the GitHub star buttons from the experimental clients: those repositories have almost no stars, so the button adds nothing next to the Get started link. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016as7phod6GN5z2g7x6ng1V --- src/pages/api/index.tsx | 66 +++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/src/pages/api/index.tsx b/src/pages/api/index.tsx index e0f0395211..b457714ade 100644 --- a/src/pages/api/index.tsx +++ b/src/pages/api/index.tsx @@ -117,37 +117,6 @@ interface ExperimentalClient { } const experimentalClients: ExperimentalClient[] = [ - { - language: 'Rust', - description: 'Async client for Tokio-based Rust applications, built on reqwest.', - repository: 'https://github.com/apify/apify-client-rust', - installLanguage: 'bash', - installSnippet: `cargo add apify-client serde_json -cargo add tokio --features macros,rt-multi-thread`, - exampleLanguage: 'rust', - exampleSnippet: `use apify_client::ApifyClient; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let client = ApifyClient::new("MY-APIFY-TOKEN"); - - // Starts an Actor and waits for it to finish. - let run = client - .actor("john-doe/my-cool-actor") - .call::(None, Default::default(), None) - .await?; - - // Fetches results from the Actor's dataset. - let dataset_id = run.default_dataset_id.expect("run has a default dataset"); - let items = client - .dataset(&dataset_id) - .list_items::(Default::default()) - .await?; - println!("Got {} items", items.items.len()); - - Ok(()) -}`, - }, { language: 'Go', description: 'Client for Go 1.23 or newer, built almost entirely on the standard library.', @@ -248,6 +217,37 @@ var run = await client.Actor("john-doe/my-cool-actor").CallAsync(null, null, nul var items = await client.Dataset(run.DefaultDatasetId!).ListItemsAsync(); Console.WriteLine($"Got {items.Count} items");`, }, + { + language: 'Rust', + description: 'Async client for Tokio-based Rust applications, built on reqwest.', + repository: 'https://github.com/apify/apify-client-rust', + installLanguage: 'bash', + installSnippet: `cargo add apify-client serde_json +cargo add tokio --features macros,rt-multi-thread`, + exampleLanguage: 'rust', + exampleSnippet: `use apify_client::ApifyClient; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = ApifyClient::new("MY-APIFY-TOKEN"); + + // Starts an Actor and waits for it to finish. + let run = client + .actor("john-doe/my-cool-actor") + .call::(None, Default::default(), None) + .await?; + + // Fetches results from the Actor's dataset. + let dataset_id = run.default_dataset_id.expect("run has a default dataset"); + let items = client + .dataset(&dataset_id) + .list_items::(Default::default()) + .await?; + println!("Got {} items", items.items.len()); + + Ok(()) +}`, + }, ]; export default function Api() { @@ -438,10 +438,6 @@ dataset_items = apify_client.dataset(actor_call['defaultDatasetId']).list_items( description={
{client.description} -