Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ slug: /actors/development/quick-start/locally

---

import QuickStartPromptButton from "@site/src/components/QuickStartPromptButton";

<QuickStartPromptButton/>

## What you'll learn

This guide walks you through the full lifecycle of an Actor. You'll start by creating and running it locally with the Apify CLI, then learn to configure its input and data storage. Finally, you will deploy the Actor to the Apify platform, making it ready to run in the cloud.
Expand Down Expand Up @@ -46,7 +50,7 @@ The CLI will:
Now, you can navigate to your new Actor directory:

```bash
cd your-actor-name
cd `your-actor-name`
```

### Step 2: Run your Actor
Expand Down
135 changes: 135 additions & 0 deletions src/components/QuickStartPromptButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import React, { useEffect, useRef, useState } from 'react';

import styles from './QuickStartPromptButton.module.css';

const PROMPT = `Follow this step-by-step workflow::

**Step 1: Verify Prerequisites**

First, verify the user's environment by running these commands:

\`\`\`bash
node --version # Requires Node.js 16 or higher
npm --version
apify --version # Check if Apify CLI is already installed
\`\`\`

If any prerequisites are missing, guide the user through installation before proceeding.

**Step 2: Install/Update Apify CLI**
\`\`\`bash
npm install -g apify-cli
\`\`\`

**Step 3: Create a New Actor**

Explain that this will prompt for actor name and template selection.

\`\`\`bash
apify create
\`\`\`

Direct users to explore templates at https://apify.com/templates.

**Step 4: Navigate to the Actor Directory**

\`\`\`bash
cd [actor-name] # Use the actual name they chose in step 3
\`\`\`

**Step 5: Run the Actor Locally**

Explain that this will run the actor locally.

\`\`\`bash
apify run
\`\`\`

**Step 6: Next Steps**

Explain that the user can deploy the actor to Apify, but they first need to log in to Apify:

\`\`\`bash
apify login
\`\`\`

After logging in, you can deploy the actor to Apify:

\`\`\`bash
apify push
\`\`\`
`;

export default function QuickStartPromptButton({ prompt = PROMPT }) {
const [copied, setCopied] = useState(false);
const [showPrompt, setShowPrompt] = useState(false);
const timeoutRef = useRef(null);

useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);

const handleCopy = async () => {
if (window.analytics) {
window.analytics.track('Clicked', {
app: 'docs',
button_text: 'Copy prompt',
element: 'quick-start-prompt-button.copyButton',
});
}

try {
await navigator.clipboard.writeText(prompt);

if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}

setCopied(true);
timeoutRef.current = setTimeout(() => setCopied(false), 2000);
} catch (err) {
console.error('Failed to copy prompt:', err);
}
};

const togglePrompt = () => {
setShowPrompt(!showPrompt);
};

return (
<>
<div className={styles['quick-start-prompt-card']}>
<div className={styles['prompt-content']}>
<div className={styles['prompt-text']}>
<span>Use this pre-built prompt to get started faster.</span>
</div>
</div>
<div className={styles['button-container']}>
<button
className={styles['toggle-button']}
onClick={togglePrompt}
>
{showPrompt ? 'Hide the prompt' : 'Show the prompt'}
</button>
<button
className={`${styles['copy-button']} ${copied ? styles.copied : ''}`}
onClick={handleCopy}
>
{copied ? 'Copied!' : 'Copy prompt'}
</button>
</div>
</div>
{showPrompt && (
<div className={styles['full-prompt-container']}>
<div className={styles['full-prompt']}>
<pre>{prompt}</pre>
</div>
</div>
)}
</>
);
}
186 changes: 186 additions & 0 deletions src/components/QuickStartPromptButton.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
.quick-start-prompt-card {
display: flex;
align-items: center;
justify-content: space-between;
background: var(--ifm-background-color);
border: 1px solid var(--ifm-color-emphasis-200);
border-radius: 8px;
padding: 1.6rem;
box-shadow: 0 1.5px 3px 0 rgb(0 0 0 / 15%);
width: 100%;
position: relative;
overflow: hidden;
}

/* Light purple glow effect */
.quick-start-prompt-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 8px;
background: linear-gradient(135deg, rgba(147, 51, 234, 0.05) 0%, transparent 50%);
pointer-events: none;
}

.prompt-content {
display: flex;
align-items: center;
gap: 0.8rem;
position: relative;
z-index: 1;
flex: 1;
}

.prompt-text {
font-size: 1.4rem;
color: var(--ifm-color-content);
font-weight: 500;
line-height: 1.4;
margin: 0;
}

.prompt-icons {
display: flex;
align-items: center;
gap: 0.4rem;
opacity: 0.4;
}

.cursor-icon {
font-size: 1.6rem;
color: var(--ifm-color-emphasis-600);
transform: rotate(-45deg);
}

.sparkle-icon {
font-size: 1.2rem;
color: var(--ifm-color-emphasis-600);
}

.copy-button {
width: 150px;
background: var(--ifm-color-primary);
color: var(--ifm-color-primary-contrast-background);
border: 1px solid var(--ifm-color-primary);
border-radius: 6px;
padding: 0.8rem 1.6rem;
font-size: 1.4rem;
font-weight: 500;
cursor: pointer;
transition: all var(--ifm-transition-fast) ease;
position: relative;
z-index: 1;
white-space: nowrap;
}

.copy-button:hover {
background: var(--ifm-color-primary-darker);
border-color: var(--ifm-color-primary-darker);
transform: translateY(-1px);
}

.copy-button:active {
transform: translateY(0);
}

.copy-button.copied {
background: var(--ifm-color-success);
border-color: var(--ifm-color-success);
}

.copy-button.copied:hover {
background: var(--ifm-color-success-darker);
border-color: var(--ifm-color-success-darker);
}

.button-container {
display: flex;
gap: 0.8rem;
align-items: center;
position: relative;
z-index: 1;
}

.toggle-button {
width: 150px;
background: transparent;
color: var(--ifm-color-primary);
border: 1px solid var(--ifm-color-primary);
border-radius: 6px;
padding: 0.8rem 1.6rem;
font-size: 1.4rem;
font-weight: 500;
cursor: pointer;
transition: all var(--ifm-transition-fast) ease;
white-space: nowrap;
flex: 1;
}

.toggle-button:hover {
background: var(--ifm-color-primary);
color: var(--ifm-color-primary-contrast-background);
transform: translateY(-1px);
}

.toggle-button:active {
transform: translateY(0);
}

.full-prompt {
margin-top: 1.2rem;
padding: 1.2rem;
background: var(--ifm-background-surface-color);
border: 1px solid var(--ifm-color-emphasis-200);
border-radius: 6px;
max-height: 400px;
overflow-y: auto;
}

.full-prompt-container {
margin-top: 1.2rem;
width: 100%;
}

.full-prompt-container .full-prompt {
margin-top: 0;
background: var(--ifm-background-color);
border: 1px solid var(--ifm-color-emphasis-200);
border-radius: 8px;
box-shadow: 0 1.5px 3px 0 rgb(0 0 0 / 15%);
}

.full-prompt pre {
margin: 0;
font-size: 1.3rem;
line-height: 1.5;
color: var(--ifm-color-content);
white-space: pre-wrap;
word-wrap: break-word;
}

/* Responsive design */
@media (max-width: 768px) {
.quick-start-prompt-card {
flex-direction: column;
gap: 1.2rem;
text-align: center;
}

.prompt-content {
flex-direction: column;
gap: 0.8rem;
}

.button-container {
flex-direction: column;
width: 100%;
}

.copy-button,
.toggle-button {
width: 100%;
}
}
Loading