@apify/docs-theme 1.0.199 → 1.0.201

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apify/docs-theme",
3
- "version": "1.0.199",
3
+ "version": "1.0.201",
4
4
  "description": "",
5
5
  "main": "./src/index.js",
6
6
  "files": [
@@ -0,0 +1,72 @@
1
+ import type React from 'react';
2
+ import { useState } from 'react';
3
+
4
+ import styles from '../styles.module.css';
5
+
6
+ // Custom component for button text
7
+ function ButtonText({ isLoading, isCopied }: { isLoading: boolean; isCopied: boolean }) {
8
+ if (isLoading) {
9
+ return 'Copying...';
10
+ }
11
+ if (isCopied) {
12
+ return 'Copied!';
13
+ }
14
+ return 'Copy for LLM';
15
+ }
16
+
17
+ export default function CopyForLLM() {
18
+ const [isLoading, setIsLoading] = useState(false);
19
+ const [isCopied, setIsCopied] = useState(false);
20
+
21
+ const handleCopy = async () => {
22
+ if ((window as any).analytics) {
23
+ (window as any).analytics.track('Clicked', {
24
+ app: 'docs',
25
+ button_text: 'Copy for LLM',
26
+ element: 'llm-buttons.copyForLLM',
27
+ });
28
+ }
29
+
30
+ try {
31
+ setIsLoading(true);
32
+
33
+ const currentUrl = window.location.href;
34
+ const markdownUrl = `${currentUrl}.md`;
35
+
36
+ // Fetch the markdown content
37
+ const response = await fetch(markdownUrl);
38
+
39
+ if (!response.ok) {
40
+ throw new Error(`Failed to fetch markdown: ${response.status}`);
41
+ }
42
+
43
+ const markdownContent = await response.text();
44
+
45
+ // Copy to clipboard
46
+ await navigator.clipboard.writeText(markdownContent);
47
+
48
+ // Show success feedback
49
+ setIsCopied(true);
50
+ setTimeout(() => setIsCopied(false), 2000);
51
+ } catch (error) {
52
+ console.error('Failed to copy markdown content:', error);
53
+ } finally {
54
+ setIsLoading(false);
55
+ }
56
+ };
57
+
58
+ return (
59
+ <button
60
+ className={styles.llmButton}
61
+ title="Copy for LLM"
62
+ onClick={handleCopy}
63
+ disabled={isLoading}
64
+ >
65
+ <span
66
+ className={`${styles.llmButtonIcon} ${styles.llmButtonIconBackgroundCopy}`}
67
+ aria-label="Copy for LLM"
68
+ />
69
+ <ButtonText isLoading={isLoading} isCopied={isCopied} />
70
+ </button>
71
+ );
72
+ }
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+
3
+ import styles from '../styles.module.css';
4
+
5
+ export default function ViewAsMarkdown() {
6
+ const handleClick = () => {
7
+ if ((window as any).analytics) {
8
+ (window as any).analytics.track('Clicked', {
9
+ app: 'docs',
10
+ button_text: 'View as Markdown',
11
+ element: 'llm-buttons.viewAsMarkdown',
12
+ });
13
+ }
14
+
15
+ try {
16
+ const currentUrl = window.location.href;
17
+ const markdownUrl = `${currentUrl}.md`;
18
+ window.open(markdownUrl, '_blank');
19
+ } catch (error) {
20
+ console.error('Error opening markdown file:', error);
21
+ }
22
+ };
23
+
24
+ return (
25
+ <button
26
+ className={styles.llmButton}
27
+ title="View as Markdown"
28
+ onClick={handleClick}
29
+ >
30
+ <span
31
+ className={`${styles.llmButtonIcon} ${styles.llmButtonIconBackgroundMarkdown}`}
32
+ aria-label="View as Markdown"
33
+ />
34
+ View as Markdown
35
+ </button>
36
+ );
37
+ }
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+
3
+ import CopyForLLM from './CopyForLLM';
4
+ import styles from './styles.module.css';
5
+ import ViewAsMarkdown from './ViewAsMarkdown';
6
+
7
+ export default function LLMButtons() {
8
+ return (
9
+ <div className={styles.llmButtonsContainer}>
10
+ <ViewAsMarkdown />
11
+ <div className={styles.llmButtonsSeparator}></div>
12
+ <CopyForLLM />
13
+ </div>
14
+ );
15
+ }
@@ -0,0 +1,57 @@
1
+ .llmButtonsContainer {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 12px;
5
+ margin-top: -8px;
6
+ margin-bottom: calc(var(--ifm-h1-vertical-rhythm-bottom) * var(--ifm-leading));
7
+ }
8
+
9
+ .llmButtonsSeparator {
10
+ width: 1px;
11
+ height: 16px;
12
+ background-color: var(--ifm-hr-background-color);
13
+ }
14
+
15
+ .llmButton {
16
+ display: flex;
17
+ align-items: center;
18
+ background-color: transparent;
19
+ border: none;
20
+ height: 16px;
21
+ cursor: pointer;
22
+ padding: 0;
23
+ gap: 4px;
24
+ }
25
+
26
+ .llmButtonIcon {
27
+ width: 16px;
28
+ height: 16px;
29
+ margin: 0 !important;
30
+ cursor: pointer;
31
+ background-size: contain;
32
+ background-repeat: no-repeat;
33
+ background-position: center;
34
+ display: inline-block;
35
+ }
36
+
37
+ .llmButtonIconBackgroundMarkdown {
38
+ background-image: url('/img/markdown.svg');
39
+
40
+ }
41
+
42
+ .llmButtonIconBackgroundCopy {
43
+ background-image: url('/img/copy.svg');
44
+ }
45
+
46
+ /* Dark theme adjustments */
47
+ [data-theme='dark'] .llmButtonIcon {
48
+ color: #e0e0e0;
49
+ }
50
+
51
+ [data-theme='dark'] .llmButtonIconBackgroundMarkdown {
52
+ background-image: url('/img/markdown-dark-theme.svg');
53
+ }
54
+
55
+ [data-theme='dark'] .llmButtonIconBackgroundCopy {
56
+ background-image: url('/img/copy-dark-theme.svg');
57
+ }
@@ -1,5 +1,5 @@
1
- import LLMButtons from '@site/src/components/LLMButtons';
2
1
  import Admonition from '@theme/Admonition';
2
+ import LLMButtons from '@theme/LLMButtons';
3
3
  import MDXA from '@theme/MDXComponents/A';
4
4
  import MDXCode from '@theme/MDXComponents/Code';
5
5
  import MDXDetails from '@theme/MDXComponents/Details';
@@ -125,9 +125,30 @@ window.addEventListener('load', () => {
125
125
 
126
126
  // docusaurus-openapi-docs plugin: scroll sidebar into viewport, no need for a large timeout here
127
127
  setTimeout(() => scrollOpenApiSidebarItemIntoView(), 200);
128
+
129
+ // MCP cache clearing - run after page is fully loaded
130
+ setTimeout(() => clearMcpRedirectCache(), 200);
128
131
  });
129
132
 
130
133
  window.addEventListener('popstate', () => {
131
134
  setTimeout(() => redirectOpenApiDocs(), 50);
132
135
  setTimeout(() => scrollOpenApiSidebarItemIntoView(), 50);
133
136
  });
137
+
138
+ // MCP redirect cache-busting
139
+ // Background: Previously, mcp.apify.com had a 301 redirect to the docs page
140
+ // This clears cached redirects so users can access the new MCP configuration interface
141
+ function clearMcpRedirectCache() {
142
+ // Only run on the MCP documentation page
143
+ if (window.location.pathname.includes('integrations/mcp')) {
144
+ // Clear cached redirects to mcp.apify.com
145
+ fetch('https://mcp.apify.com/', {
146
+ method: 'get',
147
+ cache: 'reload',
148
+ }).then(() => {
149
+ // Cache cleared successfully
150
+ }).catch(() => {
151
+ // Failed to clear cache - silent fail
152
+ });
153
+ }
154
+ }