Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Tag @apify when you share content on X.com (Twitter) or LinkedIn to potentially

---

import PromptButton from "@site/src/components/PromptButton";
import PromptBlock from "@site/src/components/PromptBlock";
import { TWITTER_POST_PROMPT } from "@site/src/utils/twitter-post-prompt";
import { LINKEDIN_POST_PROMPT } from "@site/src/utils/linkedin-post-prompt";
import { MEDIUM_ARTICLE_PROMPT } from "@site/src/utils/medium-article-prompt";
Expand All @@ -41,15 +41,15 @@ Twitter's developer community is active and engaged. A well-crafted tweet with a

Create a 30-60-second demo video or gif showing your Actor in action. Include relevant hashtags like #webscraping, #API, #automation, and #buildinpublic.

<PromptButton prompt={TWITTER_POST_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={TWITTER_POST_PROMPT} collapsed />

### Share on LinkedIn with a demo

LinkedIn reaches professionals, decision-makers, and business users with purchasing power. The platform's algorithm favors native video content, giving it 5x more reach than link posts.

Create a 30-90-second demo video showing your Actor delivering business value. Upload the video directly to LinkedIn (native videos perform better than YouTube links). Focus your post on the business problem solved, not technical features. Use 3-5 relevant hashtags like #BusinessAutomation, #Productivity, #DataIntelligence, #Efficiency, or #MarketResearch.

<PromptButton prompt={LINKEDIN_POST_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={LINKEDIN_POST_PROMPT} collapsed />

### Post in relevant Discord and Slack communities

Expand Down Expand Up @@ -168,7 +168,7 @@ Write a comprehensive "Best [CATEGORY]" roundup article (1,800-2,500 words) feat

Write in first person with a conversational yet professional tone. Include pros and cons for each solution, add a comparison table, and share your genuine perspective.

<PromptButton prompt={MEDIUM_ARTICLE_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={MEDIUM_ARTICLE_PROMPT} collapsed />

### Create a "Best X" article for dev.to

Expand All @@ -178,7 +178,7 @@ Write a developer-focused "Best [CATEGORY] for Developers" article (1,500-2,000

Write like you're advising a fellow developer: casual and helpful. Be genuinely objective about all tools, include code examples or API snippets where relevant, and use markdown formatting with H2/H3 headers.

<PromptButton prompt={DEVTO_ARTICLE_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={DEVTO_ARTICLE_PROMPT} collapsed />

### Create a "Best X" article for Hashnode

Expand All @@ -188,7 +188,7 @@ Write a technical "Best [CATEGORY] for [SPECIFIC USE CASE]: A Developer's Guide"

Include a TL;DR section at the top, use proper heading hierarchy for auto-generated table of contents, and add code examples with proper syntax highlighting. Write with technical authority but remain accessible.

<PromptButton prompt={HASHNODE_ARTICLE_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={HASHNODE_ARTICLE_PROMPT} collapsed />

### Create a "Best X" article for LinkedIn

Expand All @@ -198,7 +198,7 @@ Write a business-focused "Best [CATEGORY] for [BUSINESS OUTCOME]" article (1,200

Use a professional, authoritative but accessible tone. Focus on business impact like time savings, cost efficiency, ROI, and productivity gains rather than technical features. Include comparison tables with business-relevant metrics.

<PromptButton prompt={LINKEDIN_ARTICLE_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={LINKEDIN_ARTICLE_PROMPT} collapsed />

### Create a "How to use [Actor]" tutorial for dev.to

Expand All @@ -208,7 +208,7 @@ Write a step-by-step tutorial (1,200-2,000 words) showing developers how to use

Structure: Introduction with hook, prerequisites, what they'll achieve, step-by-step guide (access the Actor, configure inputs, run it, view results, download data), understanding results, pro tips, troubleshooting, and next steps. Write like you're helping a friend get started.

<PromptButton prompt={DEVTO_TUTORIAL_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={DEVTO_TUTORIAL_PROMPT} collapsed />

### Create a "How to use [Actor]" tutorial for Hashnode

Expand All @@ -218,7 +218,7 @@ Write a comprehensive "Complete Guide: How to [ACHIEVE OUTCOME] Using [YOUR ACTO

Include a TL;DR section, detailed step-by-step walkthrough with screenshots, API integration examples with code blocks, advanced usage patterns, troubleshooting guide, and best practices. Write with technical authority, but be thorough and maintain clarity.

<PromptButton prompt={HASHNODE_TUTORIAL_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={HASHNODE_TUTORIAL_PROMPT} collapsed />

### Create a "How to use [Actor]" tutorial for Medium

Expand All @@ -228,7 +228,7 @@ Write an accessible, engaging tutorial "How I [ACHIEVED OUTCOME] in Minutes Usin

Take a story-driven approach with personal context. Write in first person, use simple jargon-free language, and make readers feel "I can do this too." Focus on the outcome and value, not technical complexity.

<PromptButton prompt={MEDIUM_TUTORIAL_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={MEDIUM_TUTORIAL_PROMPT} collapsed />

### Create a "How to use [Actor]" tutorial for LinkedIn

Expand All @@ -238,7 +238,7 @@ Write a professional "How to [ACHIEVE BUSINESS OUTCOME] in [TIME] Using [YOUR AC

Use professional, consultative tone focused on business value. Emphasize time savings, efficiency, and ROI. Include sections on business case, measuring success, professional best practices, and real-world business applications. Address common professional questions about security, cost, reliability, and team adoption.

<PromptButton prompt={LINKEDIN_TUTORIAL_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={LINKEDIN_TUTORIAL_PROMPT} collapsed />

---

Expand All @@ -252,7 +252,7 @@ Create a GitHub repo with code examples, integration guides, or sample projects

Your README should include: project title with badges, short description, key features, quick start guide, installation and setup instructions, usage examples with code snippets, use cases section, configuration options, common questions and troubleshooting, links to Apify Store and documentation, contributing guidelines, and license.

<PromptButton prompt={GITHUB_README_PROMPT} title="Use pre-built prompt for your AI assistant" />
<PromptBlock prompt={GITHUB_README_PROMPT} collapsed />

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ unlisted: true

Want to extract data from a website? Even without knowing how to code, we can open [ChatGPT](https://chatgpt.com/) and have a scraper ready. Let's say you want to track prices from [this Sales page](https://warehouse-theme-metal.myshopify.com/collections/sales). You'd type something like:

```text
Create a scraper in JavaScript which downloads
https://warehouse-theme-metal.myshopify.com/collections/sales,
extracts all the products in Sales and saves a CSV file,
which contains:
```prompt title="Initial prompt"
Create a scraper in JavaScript which downloads https://warehouse-theme-metal.myshopify.com/collections/sales, extracts all the products in Sales and saves a CSV file, which contains:

- Product name
- Product detail page URL
Expand Down Expand Up @@ -96,20 +93,14 @@ In this course, we'll scrape a real e-commerce site instead of artificial playgr

We'll open **New chat** in [ChatGPT](https://chatgpt.com/) and prepare a beginning of a prompt like this:

```text
I'm building an Apify Actor that will run on the Apify platform.
I need to modify a sample template project so it downloads
https://warehouse-theme-metal.myshopify.com/collections/sales,
extracts all products in Sales, and returns data with
the following information for each product:
```prompt title="Update routes.js prompt"
I'm building an Apify Actor that will run on the Apify platform. I need to modify a sample template project so it downloads https://warehouse-theme-metal.myshopify.com/collections/sales, extracts all products in Sales, and returns data with the following information for each product:

- Product name
- Product detail page URL
- Price

Before the program ends, it should log how many products it collected.
Code from routes.js follows. Reply with a code block containing
a new version of that file.
Before the program ends, it should log how many products it collected. Code from routes.js follows. Reply with a code block containing a new version of that file.
```

Now let's switch back to Apify. In **Source** → **Code**, where we have the Web IDE, we'll select a file called `routes.js` inside the `src` folder. We'll see code similar to this:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ Finally, onto some agentic coding!

First, let's simplify how we can run the Actor. This will be our prompt:

```text
```prompt title="Change input URL prompt"
Change the default input URL of the Actor
to https://warehouse-theme-metal.myshopify.com/collections/sales
```
Expand Down Expand Up @@ -228,10 +228,8 @@ In the previous lesson, we noticed that the prices in our resulting dataset are

Let's change that. We'll prompt the agent like this, with a clear example of what we want:

```text
Change the code so that the Actor saves prices as numbers.
Because some prices are "from", let's call the "price" field
"minPrice" instead, as in minimum price. Example follows.
```prompt title="Clean up price data prompt"
Change the code so that the Actor saves prices as numbers. Because some prices are "from", let's call the "price" field "minPrice" instead, as in minimum price. Example follows.

Before:
Sale price$74.95
Expand All @@ -252,7 +250,7 @@ apify run

It runs, that's nice! But looking at the output, we can't really verify what exactly gets scraped! While we're at it, let's change that with another prompt:

```text
```prompt title="Log items prompt"
I want the scraper to log each item before it's saved.
```

Expand Down Expand Up @@ -308,10 +306,8 @@ We've done it, the prices save as numbers!

If we didn't want to always click on **All fields** to see full items, we need to specify an [output schema](https://docs.apify.com/actors/development/actor-definition/output-schema) so that the platform knows what it can expect and how it should display it in the interface. With Cursor, such change is just a single prompt away:

```text
Change the output schema of the Actor
so that it represents the items being
saved the best way in the Apify interface.
```prompt title="Change output schema prompt"
Change the output schema of the Actor so that it represents the items being saved the best way in the Apify interface.
```

:::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ The README documents what we already have. Now let's use it as a spec for what c

We'll save the file with <kbd>Ctrl+S</kbd> (or <kbd>⌘+S</kbd> on macOS), then send this prompt to the AI agent:

```text
```prompt title="Implement README prompt"
Ensure all behavior documented in README is correctly implemented.
```

Expand Down Expand Up @@ -181,7 +181,7 @@ Saves SKU as a number. Examples:

We'll save the file again and repeat the same prompt as before to turn our spec into code:

```text
```prompt title="Implement README prompt"
Ensure all behavior documented in README is correctly implemented.
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ _Red-green test-driven development_, often shortened to TDD, means that whenever

Now let's send this prompt to the AI agent:

```text
Read the Testing section in README and set up a test suite
covering the behavior we already have.
```prompt title="Set up test suite prompt"
Read the Testing section in README and set up a test suite covering the behavior we already have.
```

When the AI agent gets to work, you should see it create a new directory called `tests`. To create an HTML snapshot of the Sales listing, it'll probably use `curl`, a command-line program for downloading files.
Expand Down Expand Up @@ -108,9 +107,8 @@ Let's save the README and prepare a prompt for the AI agent. We'll tell it which

It's best to focus each fixture on a single situation. Our findings give us five snapshots, although some will contain the same HTML:

```text
Read the new Variants handling section and change
the project accordingly. Use red-green TDD. Fixtures:
```prompt title="Handle variants prompt"
Read the new Variants handling section and change the project accordingly. Use red-green TDD. Fixtures:

one-price-no-variants.html
https://warehouse-theme-metal.myshopify.com/products/sony-sacs9-10-inch-active-subwoofer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pagination_prev: null
---

import { AGENTS_PROMPT } from "@site/src/utils/agents-prompt";
import PromptButton from "@site/src/components/PromptButton";
import PromptBlock from "@site/src/components/PromptBlock";
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import ClaudeCodeWebEgress from '@site/sources/_partials/_claude-code-web-egress.mdx';
Expand Down Expand Up @@ -53,7 +53,7 @@ The methods on this page are complementary. Start with the [AI coding assistant

Use the following prompt in your AI coding assistant such as [Cursor](https://cursor.com/), [Claude Code](https://claude.com/product/claude-code), or [GitHub Copilot](https://github.com/features/copilot):

<PromptButton prompt={AGENTS_PROMPT} title="Use pre-built prompt for your AI coding assistant" />
<PromptBlock prompt={AGENTS_PROMPT} collapsed />

The prompt guides your AI coding assistant to create and deploy an Apify Actor step by step. It walks through setting up the Actor structure, configuring all required files, installing dependencies, running it locally, logging in, and pushing it to the Apify platform.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pagination_next: null
pagination_prev: null
---

import PromptButton from "@site/src/components/PromptButton";
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

Expand Down
37 changes: 20 additions & 17 deletions src/components/PromptButton.jsx → src/components/PromptBlock.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { useEffect, useRef, useState } from 'react';

import { QUICK_START_PROMPT } from '../utils/quick-start-prompt';
import styles from './PromptButton.module.css';
import styles from './PromptBlock.module.css';

export default function PromptButton({
prompt = QUICK_START_PROMPT,
title = 'Use pre-built prompt to get started faster.',
export default function PromptBlock({
prompt,
title = 'Ready-to-use prompt for your AI assistant',
collapsed = false,
}) {
const [copied, setCopied] = useState(false);
const [showPrompt, setShowPrompt] = useState(false);
const [showPrompt, setShowPrompt] = useState(!collapsed);
const timeoutRef = useRef(null);

useEffect(() => {
Expand All @@ -24,7 +24,7 @@ export default function PromptButton({
window.analytics.track('Clicked', {
app: 'docs',
button_text: 'Copy prompt',
element: 'prompt-button.copyButton',
element: 'prompt-block.copyButton',
});
}

Expand All @@ -48,28 +48,31 @@ export default function PromptButton({

return (
<>
<div className={styles['prompt-card']}>
<div className={`${styles['prompt-card']} ${showPrompt ? styles.open : ''}`}>
<div className={styles['prompt-content']}>
<div className={styles['prompt-text']}>
<span>{title}</span>
</div>
</div>
<div className={styles['button-container']}>
<button className={styles['toggle-button']} onClick={togglePrompt}>
{showPrompt ? 'Hide prompt' : 'Show prompt'}
</button>
{collapsed && (
<button className={styles['toggle-button']} onClick={togglePrompt}>
{showPrompt ? 'Hide prompt' : 'Show 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>
{/* Always rendered (not gated on showPrompt) so the prompt text is present in the
static HTML and gets picked up by the llms.txt generator; visibility for human
readers is controlled purely by CSS via the "visible" class below. */}
<div className={`${styles['full-prompt-container']} ${showPrompt ? styles.visible : ''}`}>
<div className={styles['full-prompt']}>
<blockquote className={styles['full-prompt-blockquote']}>{prompt}</blockquote>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using blockquote instead of pre, so that llm.txt reads more nicely, also semantics

Can you please elaborate? It seems <blockquote> is made into a single-line Markdown> quote.

Image

Not that I expect the LLMs to care much, but it's not much nicer to read for humans.

I'm not sure about the semantics either, W3C describes blockquote as a section that is quoted from another source (source). pre imo fits here better.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My sentence is wrong and it conflates few things together. The readability boost should happen for a person reading the docs, because it now word-wraps, which, I think, is desired for prompts (unlike code).

I feel like blockquote is better semantics than code, because we quote some prose we invented or tried with LLMs, and it's not technically code. In the end, perhaps https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/samp would be the closest? 😅

But tbh, I don't have a strong opinion about this. I have a strong opinion that the text of the prompt should wrap for those who read it. But I don't care that much what HTML element implements it, if it's blockquote or pre+css.

Thanks for checking the llm.txt, I didn't notice that it's a single line now, that's not really nice.

</div>
)}
</div>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,20 @@
margin-bottom: 0;
}

/* Flatten the shared edge so the toggle card and the revealed prompt read as one box */
.prompt-card.open {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}

.prompt-card.open::before {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}

/* Apply margin-bottom only when the next sibling is not a heading */
.prompt-card:not(:has(+ h1, + h2, + h3, + h4, + h5, + h6)),
.prompt-card:not(.open):not(:has(+ h1, + h2, + h3, + h4, + h5, + h6)),
.full-prompt-container:not(:has(+ h1, + h2, + h3, + h4, + h5, + h6)) {
margin-bottom: var(--ifm-leading);
}
Expand Down Expand Up @@ -158,23 +170,35 @@ html[data-theme='dark'] .toggle-button:hover {
}

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

.full-prompt-container.visible {
display: block;
}

.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%);
border-top: none;
border-radius: 0 0 8px 8px;
box-shadow: none;
}

.full-prompt pre {
.full-prompt-blockquote.full-prompt-blockquote {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels hacky (battling CSS specificity?), maybe another reason why we should keep pre?

background: var(--ifm-pre-background);
border: none;
border-radius: 4px;
box-shadow: none;
margin: 0;
padding: var(--ifm-pre-padding);
color: var(--ifm-color-content);
font-family: var(--ifm-font-family-monospace);
font-size: 1.3rem;
line-height: 1.5;
color: var(--ifm-color-content);
white-space: pre-wrap;
word-wrap: break-word;
}
Expand Down
Loading
Loading