From e178ecc9573268e41c8bd1fff165f9986b6d75b8 Mon Sep 17 00:00:00 2001 From: patrikbraborec Date: Sat, 25 Oct 2025 12:40:19 +0200 Subject: [PATCH 01/13] docs: Refactor of Build with AI section --- .../development/quick_start/build_with_ai.md | 62 ++- src/components/PromptButton.jsx | 2 +- src/utils/agents-prompt.js | 484 ++++++++++++++++++ .../{ai-prompts.js => quick-start-prompt.js} | 23 - 4 files changed, 514 insertions(+), 57 deletions(-) create mode 100644 src/utils/agents-prompt.js rename src/utils/{ai-prompts.js => quick-start-prompt.js} (54%) diff --git a/sources/platform/actors/development/quick_start/build_with_ai.md b/sources/platform/actors/development/quick_start/build_with_ai.md index 904de4c8bc..6cc8148e10 100644 --- a/sources/platform/actors/development/quick_start/build_with_ai.md +++ b/sources/platform/actors/development/quick_start/build_with_ai.md @@ -10,10 +10,29 @@ toc_max_heading_level: 4 --- -import { RULES_AND_INSTRUCTIONS_PROMPT } from "@site/src/utils/ai-prompts"; +import { AGENTS_PROMPT } from "@site/src/utils/agents-prompt"; import PromptButton from "@site/src/components/PromptButton"; -This guide explains how to enhance your development workflow by leveraging `llms.txt` and `llms-full.txt` with an AI assistant. You will learn how to provide foundational context and further refine AI's behavior with specific rules and instruction files. +This guide shows you how to build Actors efficiently with AI coding assistants. You'll learn how to use pre-built instructions, integrate Apify documentation into your AI editor, and apply best practices for AI-assisted development. + +## AI coding assistant instructions + +Use the following prompt in your favorite AI coding assistant: + + + +### Quick Start + +- _Step 1_: Create directory: `mkdir my-new-actor` +- _Step 2_: Open the directory in _Cursor_, _VS Code_, etc. +- _Step 3_: Copy the prompt above and paste it into your AI coding assistant (Agent or Chat) +- _Step 4_: Run it, and develop your first actor with the help of AI πŸŽ‰ + +:::info Start in an AI coding assistant + +To maximize efficiency, copy the prompt to Cursor, VS Code with GitHub Copilot, or another AI coding assistant. The AI will follow the guide step-by-step, and you'll avoid copy-pasting from tools like ChatGPT or Claude. + +::: ## `llms.txt` and `llms-full.txt` @@ -40,6 +59,8 @@ Search engines weren't built for Large Language Models (LLMs), but they needs co + + ### Use llms.txt and llms-full.txt LLMs don't automatically discover `llms.txt` files, you need to add the link manually. Some tools like [Cursor](https://www.cursor.com/) provide settings for this. @@ -86,42 +107,17 @@ New to Apify? Ask questions and provide the `llms.txt` link. Popular AI models c ![Ask about Apify](./images/claude.png) -## View pages as markdown - -Every page in Apify documentation is available in markdown format. Simply add `.md` to any documentation URL to access the raw markdown content. +## Use Actor Templates with instructions -For example: +TODO: -- [https://docs.apify.com/platform](https://docs.apify.com/platform) β†’ [https://docs.apify.com/platform.md](https://docs.apify.com/platform.md) -- [https://docs.apify.com/api](https://docs.apify.com/api) β†’ [https://docs.apify.com/api.md](https://docs.apify.com/api.md) +- Just mention that you can init actor using `apify create` and use it in IDE with AGENTS.md -This is useful when you want to: +## Provide context to assistants -- Copy documentation content for AI prompts -- Reference exact markdown syntax -- Access content programmatically +TBD: -## Add rules - -To get the most from AI Code Editors, add rules or instructions. - -See how to set up rules for your AI Code Editors: - -- [Cursor Rules](https://docs.cursor.com/en/context/rules) -- [Windsurf Rules](https://docs.windsurf.com/windsurf/cascade/memories#rules) -- [GitHub Copilot instructions](https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions) - -### Apify rules and instructions - -The best rules and instructions are specific for individual use cases, but we provide a prompt to help you get start with creating rules and instructions: - - - -:::info Keep your rules and instructions up to date - -As the project evolves, you might introduce new things. Always make sure that your rules and instructions are up to date. - -::: +- Mention "Copy for LLM" buttons ## Best practices diff --git a/src/components/PromptButton.jsx b/src/components/PromptButton.jsx index da51468ef1..be4275055c 100644 --- a/src/components/PromptButton.jsx +++ b/src/components/PromptButton.jsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; -import { QUICK_START_PROMPT } from '../utils/ai-prompts'; +import { QUICK_START_PROMPT } from '../utils/quick-start-prompt'; import styles from './PromptButton.module.css'; export default function PromptButton({ prompt = QUICK_START_PROMPT, title = 'Use pre-built prompt to get started faster.' }) { diff --git a/src/utils/agents-prompt.js b/src/utils/agents-prompt.js new file mode 100644 index 0000000000..724b0411b7 --- /dev/null +++ b/src/utils/agents-prompt.js @@ -0,0 +1,484 @@ +// TODO: +// - It did not use apify run correctly +// - It did not use version in actor.json correctly (it should be 0.0 and not 0.0.1) +// - It did not create AGENTS.md file correctly + +export const AGENTS_PROMPT = `Instruct the user on how to develop an Actor step by step: + +- Start with first steps like create directory for Actor, suggest to use it in Cursor or other AI tools that support AI coding assistants. +- Based on the structure of the Actor, fill in the default and example values for all fields in the actor.json, input_schema.json, output_schema.json, and main.js files +- Install dependencies for the Actor using \`npm install\` +- Run the Actor locally using \`apify run\` +- Log in to the Apify platform using \`apify login\` +- Push the Actor to the Apify platform using \`apify push\` +- Create AGENTS.md file based provided instructions in this prompt, but ignore the getting started section. +- Important: Before you begin with coding, fill in the model property in the meta section of \`.actor/actor.json\`. Replace it with the model you're currently using. This helps Apify monitor and improve AGENTS.md for specific LLM models. + +## What are Apify Actors? + +- Actors are serverless programs that run in the cloud. They're inspired by the UNIX philosophy - programs that do one thing well and can be easily combined to build complex systems. +- Actors are programs packaged as Docker images that run in isolated containers + +## Structure of Apify Actor + +Important: + +- Do not change the structure of the Actor. +- Do not initialize the storage directory. + +.actor/ +β”œβ”€β”€ actor.json # Actor config: name, version, env vars, runtime settings +β”œβ”€β”€ input_schema.json # Input validation & Console form definition +β”œβ”€β”€ dataset_schema.json # Dataset schema definition +└── output_schema.json # Specifies where an Actor stores its output +src/ +└── main.js # Actor entry point and orchestrator +storage/ # Local storage (mirrors Cloud during development) +β”œβ”€β”€ datasets/ # Output items (JSON objects) +β”œβ”€β”€ key_value_stores/ # Files, config, INPUT +└── request_queues/ # Pending crawl requests +Dockerfile # Container image definition +AGENTS.md # AI agent instructions (this file) + +### actor.json (default and example values) + +\`\`\`json +{ + "actorSpecification": 1, + "name": "", + "title": "", + "description": "", + "version": "", + "meta": { + "templateId": "ai-generated-actor", + "model": "" + }, + "input": "./input_schema.json", + "output": "./output_schema.json", + "storages": { + "dataset": "./dataset_schema.json" + }, + "dockerfile": "../Dockerfile" +} +\`\`\` + +### input_schema.json (default and example values) + +\`\`\`json +{ + "title": "CheerioCrawler Template", + "type": "object", + "schemaVersion": 1, + "properties": { + "startUrls": { + "title": "Start URLs", + "type": "array", + "description": "URLs to start with.", + "editor": "requestListSources", + "prefill": [ + { + "url": "https://crawlee.dev" + } + ] + }, + "maxRequestsPerCrawl": { + "title": "Max Requests per Crawl", + "type": "integer", + "description": "Maximum number of requests that can be made by this crawler.", + "default": 100 + } + } +} +\`\`\` + +### output_schema.json (default and example values) + +\`\`\`json +{ + "actorOutputSchemaVersion": 1, + "title": "Output schema of the files scraper", + "properties": { + "overview": { + "type": "string", + "title": "Overview", + "template": "{{links.apiDefaultDatasetUrl}}/items?view=overview" + } + } +} +\`\`\` + +### dataset_schema.json (default and example values) + +\`\`\`json +{ + "actorSpecification": 1, + "fields": {}, + "views": { + "overview": { + "title": "Overview", + "transformation": { + "fields": ["title", "url"] + }, + "display": { + "component": "table", + "properties": { + "title": { + "label": "Title", + "format": "text" + }, + "url": { + "label": "URL", + "format": "link" + } + } + } + } + } +} +\`\`\` + +### main.js (default and example values) + +\`\`\`javascript +// Apify SDK - toolkit for building Apify Actors (Read more at https://docs.apify.com/sdk/js/) +import { Actor } from 'apify'; +// Crawlee - web scraping and browser automation library (Read more at https://crawlee.dev) +import { CheerioCrawler, Dataset } from 'crawlee'; + +// The init() call configures the Actor for its environment. It's recommended to start every Actor with an init() +await Actor.init(); + +// Structure of input is defined in input_schema.json +const { startUrls = ['https://apify.com'], maxRequestsPerCrawl = 100 } = (await Actor.getInput()) ?? {}; + +// Proxy configuration to rotate IP addresses and prevent blocking (https://docs.apify.com/platform/proxy) +const proxyConfiguration = await Actor.createProxyConfiguration(); + +const crawler = new CheerioCrawler({ + proxyConfiguration, + maxRequestsPerCrawl, + async requestHandler({ enqueueLinks, request, $, log }) { + log.info('enqueueing new URLs'); + await enqueueLinks(); + + // Extract title from the page. + const title = $('title').text(); + log.info(\`\${title}\`, { url: request.loadedUrl }); + + // Save url and title to Dataset - a table-like storage. + await Dataset.pushData({ url: request.loadedUrl, title }); + }, +}); + +await crawler.run(startUrls); + +// Gracefully exit the Actor process. It's recommended to quit all Actors with an exit() +await Actor.exit(); +\`\`\` + +### Dockerfile (default values) + +\`\`\`dockerfile +# Specify the base Docker image. You can read more about +# the available images at https://docs.apify.com/sdk/js/docs/guides/docker-images +# You can also use any other image from Docker Hub. +FROM apify/actor-node:22 + +# Check preinstalled packages +RUN npm ls crawlee apify puppeteer playwright + +# Copy just package.json and package-lock.json +# to speed up the build using Docker layer cache. +COPY --chown=myuser:myuser package*.json ./ + +# Install NPM packages, skip optional and development dependencies to +# keep the image small. Avoid logging too much and print the dependency +# tree for debugging +RUN npm --quiet set progress=false \ + && npm install --omit=dev --omit=optional \ + && echo "Installed NPM packages:" \ + && (npm list --omit=dev --all || true) \ + && echo "Node.js version:" \ + && node --version \ + && echo "NPM version:" \ + && npm --version \ + && rm -r ~/.npm + +# Next, copy the remaining files and directories with the source code. +# Since we do this after NPM install, quick build will be really fast +# for most source file changes. +COPY --chown=myuser:myuser . ./ + +# Run the image. +CMD npm start --silent +\`\`\` + +### package.json (default values) + +\`\`\`json +{ + "name": "", + "version": "0.0.1", + "type": "module", + "description": "", + "engines": { + "node": ">=20.0.0" + }, + "dependencies": { + "apify": "^3.4.2", + "crawlee": "^3.13.8" + }, + "devDependencies": { + "@apify/eslint-config": "^1.0.0", + "eslint": "^9.29.0", + "eslint-config-prettier": "^10.1.5", + "prettier": "^3.5.3" + }, + "scripts": { + "start": "node src/main.js", + "format": "prettier --write .", + "format:check": "prettier --check .", + "lint": "eslint", + "lint:fix": "eslint --fix", + "test": "echo \"Error: oops, the Actor has no tests yet, sad!\" && exit 1" + }, + "author": "It's not you it's me", + "license": "ISC" +} +\`\`\` + +## Apify CLI + +### Installation + +#### macOS/Linux + +\`\`\`bash +curl -fsSL https://apify.com/install-cli.sh | bash +\`\`\` + +#### Windows + +\`\`\`bash +irm https://apify.com/install-cli.ps1 | iex +\`\`\` + +### Apify CLI Commands + +\`\`\`bash +# Local development +apify run # Run Actor locally + +# Authentication & deployment +apify login # Authenticate account +apify push # Deploy to Apify platform + +# Help +apify help # List all commands +\`\`\` + +## Do + +- use the default values for all fields in the actor.json, input_schema.json, output_schema.json, and main.js files +- use Apify CLI to run the Actor locally, and push it to the Apify platform +- accept well-defined JSON input and produce structured JSON output +- use Apify SDK (\`apify\`) for code running ON Apify platform +- validate input early with proper error handling and fail gracefully +- use CheerioCrawler for static HTML content (10x faster than browsers) +- use PlaywrightCrawler only for JavaScript-heavy sites and dynamic content +- use router pattern (createCheerioRouter/createPlaywrightRouter) for complex crawls +- implement retry strategies with exponential backoff for failed requests +- use proper concurrency settings (HTTP: 10-50, Browser: 1-5) +- set sensible defaults in \`.actor/input_schema.json\` for all optional fields +- set up output schema in \`.actor/output_schema.json\` +- clean and validate data before pushing to dataset +- use semantic CSS selectors and fallback strategies for missing elements +- respect robots.txt, ToS, and implement rate limiting with delays +- check which tools (cheerio/playwright/crawlee) are installed before applying guidance + +## Don't + +- do not run apify create command +- do not rely on \`Dataset.getInfo()\` for final counts on Cloud platform +- do not use browser crawlers when HTTP/Cheerio works (massive performance gains with HTTP) +- do not hard code values that should be in input schema or environment variables +- do not skip input validation or error handling +- do not overload servers - use appropriate concurrency and delays +- do not scrape prohibited content or ignore Terms of Service +- do not store personal/sensitive data unless explicitly permitted +- do not use deprecated options like \`requestHandlerTimeoutMillis\` on CheerioCrawler (v3.x) +- do not use \`additionalHttpHeaders\` - use \`preNavigationHooks\` instead + +## Actor Input Schema + +The input schema defines the input parameters for an Actor. It's a JSON object comprising various field types supported by the Apify platform. + +### Structure + +\`\`\`json +{ + "title": "", + "type": "object", + "schemaVersion": 1, + "properties": { + /* define input fields here */ + }, + "required": [] +} +\`\`\` + +## Actor Output Schema + +The Actor output schema builds upon the schemas for the dataset and key-value store. It specifies where an Actor stores its output and defines templates for accessing that output. Apify Console uses these output definitions to display run results. + +### Structure + +\`\`\`json +{ + "actorOutputSchemaVersion": 1, + "title": "", + "properties": { + /* define your outputs here */ + } +} +\`\`\` + +### Output Schema Template Variables + +- \`links\` (object) - Contains quick links to most commonly used URLs +- \`links.publicRunUrl\` (string) - Public run url in format \`https://console.apify.com/view/runs/:runId\` +- \`links.consoleRunUrl\` (string) - Console run url in format \`https://console.apify.com/actors/runs/:runId\` +- \`links.apiRunUrl\` (string) - API run url in format \`https://api.apify.com/v2/actor-runs/:runId\` +- \`links.apiDefaultDatasetUrl\` (string) - API url of default dataset in format \`https://api.apify.com/v2/datasets/:defaultDatasetId\` +- \`links.apiDefaultKeyValueStoreUrl\` (string) - API url of default key-value store in format \`https://api.apify.com/v2/key-value-stores/:defaultKeyValueStoreId\` +- \`links.containerRunUrl\` (string) - URL of a webserver running inside the run in format \`https://.runs.apify.net/\` +- \`run\` (object) - Contains information about the run same as it is returned from the \`GET Run\` API endpoint +- \`run.defaultDatasetId\` (string) - ID of the default dataset +- \`run.defaultKeyValueStoreId\` (string) - ID of the default key-value store + +## Dataset Schema Specification + +The dataset schema defines how your Actor's output data is structured, transformed, and displayed in the Output tab in the Apify Console. + +### Structure + +\`\`\`json +{ + "actorSpecification": 1, + "fields": {}, + "views": { + "": { + "title": "string (required)", + "description": "string (optional)", + "transformation": { + "fields": ["string (required)"], + "unwind": ["string (optional)"], + "flatten": ["string (optional)"], + "omit": ["string (optional)"], + "limit": "integer (optional)", + "desc": "boolean (optional)" + }, + "display": { + "component": "table (required)", + "properties": { + "": { + "label": "string (optional)", + "format": "text|number|date|link|boolean|image|array|object (optional)" + } + } + } + } + } +} +\`\`\` + +**Dataset Schema Properties:** + +- \`actorSpecification\` (integer, required) - Specifies the version of dataset schema structure document (currently only version 1) +- \`fields\` (JSONSchema object, required) - Schema of one dataset object (use JsonSchema Draft 2020-12 or compatible) +- \`views\` (DatasetView object, required) - Object with API and UI views description + +**DatasetView Properties:** + +- \`title\` (string, required) - Visible in UI Output tab and API +- \`description\` (string, optional) - Only available in API response +- \`transformation\` (ViewTransformation object, required) - Data transformation applied when loading from Dataset API +- \`display\` (ViewDisplay object, required) - Output tab UI visualization definition + +**ViewTransformation Properties:** + +- \`fields\` (string[], required) - Fields to present in output (order matches column order) +- \`unwind\` (string[], optional) - Deconstructs nested children into parent object +- \`flatten\` (string[], optional) - Transforms nested object into flat structure +- \`omit\` (string[], optional) - Removes specified fields from output +- \`limit\` (integer, optional) - Maximum number of results (default: all) +- \`desc\` (boolean, optional) - Sort order (true = newest first) + +**ViewDisplay Properties:** + +- \`component\` (string, required) - Only \`table\` is available +- \`properties\` (Object, optional) - Keys matching \`transformation.fields\` with ViewDisplayProperty values + +**ViewDisplayProperty Properties:** + +- \`label\` (string, optional) - Table column header +- \`format\` (string, optional) - One of: \`text\`, \`number\`, \`date\`, \`link\`, \`boolean\`, \`image\`, \`array\`, \`object\` + +## Key-Value Store Schema Specification + +The key-value store schema organizes keys into logical groups called collections for easier data management. + +### Structure + +\`\`\`json +{ + "actorKeyValueStoreSchemaVersion": 1, + "title": "string (required)", + "description": "string (optional)", + "collections": { + "": { + "title": "string (required)", + "description": "string (optional)", + "key": "string (conditional - use key OR keyPrefix)", + "keyPrefix": "string (conditional - use key OR keyPrefix)", + "contentTypes": ["string (optional)"], + "jsonSchema": "object (optional)" + } + } +} +\`\`\` + +**Key-Value Store Schema Properties:** + +- \`actorKeyValueStoreSchemaVersion\` (integer, required) - Version of key-value store schema structure document (currently only version 1) +- \`title\` (string, required) - Title of the schema +- \`description\` (string, optional) - Description of the schema +- \`collections\` (Object, required) - Object where each key is a collection ID and value is a Collection object + +**Collection Properties:** + +- \`title\` (string, required) - Collection title shown in UI tabs +- \`description\` (string, optional) - Description appearing in UI tooltips +- \`key\` (string, conditional) - Single specific key for this collection +- \`keyPrefix\` (string, conditional) - Prefix for keys included in this collection +- \`contentTypes\` (string[], optional) - Allowed content types for validation +- \`jsonSchema\` (object, optional) - JSON Schema Draft 07 format for \`application/json\` content type validation + +Either \`key\` or \`keyPrefix\` must be specified for each collection, but not both. + +## Apify MCP Tools + +If MCP server is configured, use these tools for documentation: + +- \`search-apify-docs\` - Search documentation +- \`fetch-apify-docs\` - Get full doc pages + +Otherwise, reference: \`@https://mcp.apify.com/\` + +## Resources + +- [docs.apify.com/llms.txt](https://docs.apify.com/llms.txt) - Quick reference +- [docs.apify.com/llms-full.txt](https://docs.apify.com/llms-full.txt) - Complete docs +- [crawlee.dev](https://crawlee.dev) - Crawlee documentation +- [whitepaper.actor](https://raw.githubusercontent.com/apify/actor-whitepaper/refs/heads/master/README.md) - Complete Actor specification +`; diff --git a/src/utils/ai-prompts.js b/src/utils/quick-start-prompt.js similarity index 54% rename from src/utils/ai-prompts.js rename to src/utils/quick-start-prompt.js index d831af50ef..3bd0f01914 100644 --- a/src/utils/ai-prompts.js +++ b/src/utils/quick-start-prompt.js @@ -57,26 +57,3 @@ After logging in, you can deploy the actor to Apify: apify push \`\`\` `; - -export const RULES_AND_INSTRUCTIONS_PROMPT = `Using the Apify documentation as reference, create a comprehensive rules file for [PLACEHOLDER (Cursor, Windsurf, GitHub Copilot, etc.)] focused on developing Apify Actors. - -Follow these best practices for creating effective rules: -- Keep rules simple, concise, and specific (avoid vague or generic advice) -- Use bullet points, numbered lists, and clear markdown formatting -- Focus on actionable guidelines rather than explanations - -Create the rules file in the appropriate location: -- For Cursor: Save as \`.cursor/rules/apify-development.md\` -- For Windsurf: Save as \`.windsurf/rules/apify-development.md\` -- For GitHub Copilot: Save as \`.github/copilot-instructions.md\` - -The rules should be: -- Clear and specific for Apify platform development -- Formatted as bullet points with section headers -- Create rules based on existing code in the project - -Include sections for: -- Actor development & structure -- Apify SDK usage patterns - -Reference Apify documentation at https://docs.apify.com/llms-full.txt for accurate patterns and recommendations. Keep each rule concise and practical for actor development. Format as markdown with # headers and - bullet points.`; From e0c33880d40ada0ee97817c434599101230f7d2e Mon Sep 17 00:00:00 2001 From: patrikbraborec Date: Sat, 25 Oct 2025 12:44:05 +0200 Subject: [PATCH 02/13] docs: Fix lint errors --- src/utils/agents-prompt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/agents-prompt.js b/src/utils/agents-prompt.js index 724b0411b7..3e97804915 100644 --- a/src/utils/agents-prompt.js +++ b/src/utils/agents-prompt.js @@ -240,7 +240,7 @@ CMD npm start --silent "format:check": "prettier --check .", "lint": "eslint", "lint:fix": "eslint --fix", - "test": "echo \"Error: oops, the Actor has no tests yet, sad!\" && exit 1" + "test": "echo 'Error: oops, the Actor has no tests yet, sad!' && exit 1" }, "author": "It's not you it's me", "license": "ISC" From 3111ae2fadfb08cf1ff63b8c2c720557c974188c Mon Sep 17 00:00:00 2001 From: patrikbraborec Date: Sun, 26 Oct 2025 11:06:18 +0100 Subject: [PATCH 03/13] docs: Refactor of Build with AI section - v2 --- .../development/quick_start/build_with_ai.md | 114 ++++++++---------- .../quick_start/images/copy-for-llm.png | Bin 0 -> 74301 bytes src/components/InstallMCPButton.jsx | 26 ++++ src/components/InstallMCPButton.module.css | 54 +++++++++ src/components/PromptButton.module.css | 2 - src/utils/agents-prompt.js | 87 +++++++------ 6 files changed, 182 insertions(+), 101 deletions(-) create mode 100644 sources/platform/actors/development/quick_start/images/copy-for-llm.png create mode 100644 src/components/InstallMCPButton.jsx create mode 100644 src/components/InstallMCPButton.module.css diff --git a/sources/platform/actors/development/quick_start/build_with_ai.md b/sources/platform/actors/development/quick_start/build_with_ai.md index 6cc8148e10..72dba259fc 100644 --- a/sources/platform/actors/development/quick_start/build_with_ai.md +++ b/sources/platform/actors/development/quick_start/build_with_ai.md @@ -1,30 +1,32 @@ --- title: Build with AI sidebar_position: 3 -description: Learn how to set up your environment, choose the right tools, and establish workflows for effective vibe coding +description: Use pre-built prompts, use Apify docs via llms.txt, and follow best practices to effective vibe coding. slug: /actors/development/quick-start/build-with-ai toc_max_heading_level: 4 --- -**Set up your environment, choose tools, and build workflows for effective AI development.** +**Use pre-built prompts, use Apify docs via llms.txt, and follow best practices to build Actors efficiently with AI assistants.** --- import { AGENTS_PROMPT } from "@site/src/utils/agents-prompt"; import PromptButton from "@site/src/components/PromptButton"; +import InstallMCPButton from "@site/src/components/InstallMCPButton"; +import copyForLlm from "./images/copy-for-llm.png"; This guide shows you how to build Actors efficiently with AI coding assistants. You'll learn how to use pre-built instructions, integrate Apify documentation into your AI editor, and apply best practices for AI-assisted development. ## AI coding assistant instructions -Use the following prompt in your favorite AI coding assistant: +Use the following prompt in your AI coding assistant ([Cursor](https://www.cursor.com/), [Claude Code](https://www.claude.com/product/claude-code), [GitHub Copilot](https://github.com/features/copilot), etc.): ### Quick Start - _Step 1_: Create directory: `mkdir my-new-actor` -- _Step 2_: Open the directory in _Cursor_, _VS Code_, etc. +- _Step 2_: Open the directory in _Cursor_, _Claude Code_, _VS Code with GitHub Copilot_, etc. - _Step 3_: Copy the prompt above and paste it into your AI coding assistant (Agent or Chat) - _Step 4_: Run it, and develop your first actor with the help of AI πŸŽ‰ @@ -34,9 +36,51 @@ To maximize efficiency, copy the prompt to Cursor, VS Code with GitHub Copilot, ::: -## `llms.txt` and `llms-full.txt` +## Use Actor templates with AGENTS.md -Search engines weren't built for Large Language Models (LLMs), but they needs context. That's why we've created [`llms.txt`](https://docs.apify.com/llms.txt) and [`llms-full.txt`](https://docs.apify.com/llms-full.txt) for our documentation. These files follow the [growing standard](https://llmstxt.org/) for LLMs consumption. +All [Actor Templates](https://apify.com/templates) have AGENTS.md that will help you with AI coding. If you prefer a more traditional approach, run the following command: + +:::info Install Apify CLI + +If you don't have Apify CLI installed, install it first. Check the [installation guide](/cli/docs/installation). + +::: + +```bash +apify create +``` + +The command above will guide you through Apify Actor initialization, where you select an Actor Template that works for you. The result is an initialized Actor (with AGENTS.md) ready for development. + +## Use Apify MCP Server + +The Apify MCP Server has tools to search and fetch documentation. If you set it up in your AI editor, it will help you improve the generated code by providing additional context to the AI. + +Install it by clicking one of the following buttons for your AI editor. + +### Cursor + + + +### VS Code + + + +### Claude Code + +```bash +claude mcp add apify https://mcp.apify.com/?tools=docs -t http +``` + +## Provide context to assistants + +Every page in the Apify documentation has a _Copy for LLM_ button. You can use it to add additional context to your AI assistant, or even open the page in ChatGPT, Claude, or Perplexity and ask additional questions. + +Copy for LLM + +## Use `llms.txt` and `llms-full.txt` + +Search engines weren't built for Large Language Models (LLMs), but LLMs need context. That's why we've created [`llms.txt`](https://docs.apify.com/llms.txt) and [`llms-full.txt`](https://docs.apify.com/llms-full.txt) for our documentation. These files can provide additional context if you link them. @@ -59,66 +103,12 @@ Search engines weren't built for Large Language Models (LLMs), but they needs co
- - -### Use llms.txt and llms-full.txt - -LLMs don't automatically discover `llms.txt` files, you need to add the link manually. Some tools like [Cursor](https://www.cursor.com/) provide settings for this. - -#### Cursor +:::note Provide link to AI assistants -Go to: **Settings -> Cursor Settings -> Indexing & Docs -> Add Doc**. - -Now, you can just provide the link to Apify `llms-full.txt`: - -```markdown -https://docs.apify.com/llms-full.txt -``` - -![Add llms-full.txt to Cursor](./images/cursor.png) - -#### Windsurf - -Open Windsurf Cascade, and add context via `@web`: - -![Add llms-full.txt to Windsurf](./images/windsurf.png) - -:::note Windsurf @docs - -Windsurf provides the `@docs` command, but you cannot customize it. It means that you cannot add your own documentation. - -::: - -#### GitHub Copilot - -Open Copilot Chat mode, and add context via `#fetch`: - -![Add llms.txt to Copilot](./images/github-copilot.png) - -:::note GitHub Copilot and documentation - -Similar to Windsurf, GitHub Copilot does not provide an option for adding your own documentation. +LLMs don't automatically discover `llms.txt` files, you need to add the link manually to improve the quality of answers. ::: -#### Ask AI - -New to Apify? Ask questions and provide the `llms.txt` link. Popular AI models can search the web. With the right context, you get better answers: - -![Ask about Apify](./images/claude.png) - -## Use Actor Templates with instructions - -TODO: - -- Just mention that you can init actor using `apify create` and use it in IDE with AGENTS.md - -## Provide context to assistants - -TBD: - -- Mention "Copy for LLM" buttons - ## Best practices - _Small tasks_: Don't ask AI for many tasks at once. Break complex problems into smaller pieces. Solve them step by step. diff --git a/sources/platform/actors/development/quick_start/images/copy-for-llm.png b/sources/platform/actors/development/quick_start/images/copy-for-llm.png new file mode 100644 index 0000000000000000000000000000000000000000..183ebc7d2d7a4f7ca7afc96a5de33543812afec7 GIT binary patch literal 74301 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 +

+ + ); +} diff --git a/src/components/InstallMCPButton.module.css b/src/components/InstallMCPButton.module.css new file mode 100644 index 0000000000..632113a368 --- /dev/null +++ b/src/components/InstallMCPButton.module.css @@ -0,0 +1,54 @@ +.wrapper { + display: flex; + justify-content: center; + align-items: center; + color: var(--ifm-color-content); +} + +.button { + width: fit-content; + display: inline-flex; + align-items: center; + height: 3rem; + + display: flex; + align-items: center; + border-radius: 8px; + border: 1px solid var(--color-Neutral_SeparatorSubtle); + background-color: var(--color-Neutral_BackgroundMuted); + + cursor: pointer; + transition: background-color 0.2s ease-in-out; + + &:hover { + background-color: var(--color-Neutral_BackgroundMuted); + } +} + +.label { + height: 100%; + display: flex; + align-items: center; + padding-right: 0.8rem; + min-width: 9.3rem; + + /* prevents font size glitch when loading the page */ + margin: 0px; + font-size: 1.4rem; + font-weight: 400; + font-family: Inter, sans-serif; +} + +.button:hover { + background-color: var(--color-Neutral_BackgroundMuted); + color: var(--ifm-color-content); +} + +.iconWrapper { + display: flex; + align-items: center; + justify-content: center; + padding-left: 0.8rem; + padding-right: 0.4rem; + height: 100%; +} diff --git a/src/components/PromptButton.module.css b/src/components/PromptButton.module.css index 8cec6aa68b..ab4337310c 100644 --- a/src/components/PromptButton.module.css +++ b/src/components/PromptButton.module.css @@ -85,7 +85,6 @@ .copy-button:hover { background: var(--ifm-color-primary-darker); border-color: var(--ifm-color-primary-darker); - transform: translateY(-1px); } .copy-button:active { @@ -128,7 +127,6 @@ .toggle-button:hover { background: var(--ifm-color-primary); color: var(--ifm-color-primary-contrast-background); - transform: translateY(-1px); } .toggle-button:active { diff --git a/src/utils/agents-prompt.js b/src/utils/agents-prompt.js index 3e97804915..0b0197e5ed 100644 --- a/src/utils/agents-prompt.js +++ b/src/utils/agents-prompt.js @@ -1,31 +1,25 @@ -// TODO: -// - It did not use apify run correctly -// - It did not use version in actor.json correctly (it should be 0.0 and not 0.0.1) -// - It did not create AGENTS.md file correctly - export const AGENTS_PROMPT = `Instruct the user on how to develop an Actor step by step: -- Start with first steps like create directory for Actor, suggest to use it in Cursor or other AI tools that support AI coding assistants. +- Start with first steps like creating a directory for the Actor, suggest to use it in Cursor or other AI tools that support AI coding assistants. +- Ask the user to provide the name of the Actor - Based on the structure of the Actor, fill in the default and example values for all fields in the actor.json, input_schema.json, output_schema.json, and main.js files - Install dependencies for the Actor using \`npm install\` -- Run the Actor locally using \`apify run\` -- Log in to the Apify platform using \`apify login\` -- Push the Actor to the Apify platform using \`apify push\` -- Create AGENTS.md file based provided instructions in this prompt, but ignore the getting started section. -- Important: Before you begin with coding, fill in the model property in the meta section of \`.actor/actor.json\`. Replace it with the model you're currently using. This helps Apify monitor and improve AGENTS.md for specific LLM models. - -## What are Apify Actors? - -- Actors are serverless programs that run in the cloud. They're inspired by the UNIX philosophy - programs that do one thing well and can be easily combined to build complex systems. -- Actors are programs packaged as Docker images that run in isolated containers +- Run the Actor locally using \`apify run\` - this is the exact command to use, do not change it. +- Log in to the Apify platform using \`apify login\` - this is the exact command to use, do not change it. +- Push the Actor to the Apify platform using \`apify push\` - this is the exact command to use, do not change it. +- Create AGENTS.md - copy the content of this file from the "What are Apify Actors?" section and all content below it to the new file. +- Important: Before you begin coding, fill in the model property in the meta section of \`.actor/actor.json\`. Replace it with the model you're currently using. This helps Apify monitor and improve AGENTS.md for specific LLM models. -## Structure of Apify Actor +## Structure of initial Apify Actor -Important: +### Important -- Do not change the structure of the Actor. -- Do not initialize the storage directory. +- the initial structure of the Actor is scraper example that uses Cheerio and Crawlee to parse HTML. It's fast, but it can't run the website's JavaScript or pass JS anti-scraping challenges. +- do not use version in actor.json other than 0.0 (initial version). +- do not change the structure of the initial Actor. +- do not initialize the storage directory. +\`\`\`text .actor/ β”œβ”€β”€ actor.json # Actor config: name, version, env vars, runtime settings β”œβ”€β”€ input_schema.json # Input validation & Console form definition @@ -39,16 +33,17 @@ storage/ # Local storage (mirrors Cloud during development) └── request_queues/ # Pending crawl requests Dockerfile # Container image definition AGENTS.md # AI agent instructions (this file) +\`\`\` ### actor.json (default and example values) \`\`\`json { "actorSpecification": 1, - "name": "", - "title": "", - "description": "", - "version": "", + "name": "", + "title": "", + "description": "", + "version": "0.0", "meta": { "templateId": "ai-generated-actor", "model": "" @@ -66,7 +61,7 @@ AGENTS.md # AI agent instructions (this file) \`\`\`json { - "title": "CheerioCrawler Template", + "title": "Input schema of the ", "type": "object", "schemaVersion": 1, "properties": { @@ -96,7 +91,7 @@ AGENTS.md # AI agent instructions (this file) \`\`\`json { "actorOutputSchemaVersion": 1, - "title": "Output schema of the files scraper", + "title": "Output schema of the ", "properties": { "overview": { "type": "string", @@ -139,6 +134,8 @@ AGENTS.md # AI agent instructions (this file) ### main.js (default and example values) +- The code is a JavaScript script that uses Cheerio to scrape data from a website. It then stores the website titles in a dataset. + \`\`\`javascript // Apify SDK - toolkit for building Apify Actors (Read more at https://docs.apify.com/sdk/js/) import { Actor } from 'apify'; @@ -217,10 +214,10 @@ CMD npm start --silent \`\`\`json { - "name": "", + "name": "", "version": "0.0.1", "type": "module", - "description": "", + "description": "", "engines": { "node": ">=20.0.0" }, @@ -247,21 +244,37 @@ CMD npm start --silent } \`\`\` -## Apify CLI +## What are Apify Actors? -### Installation +- Actors are serverless cloud programs that can perform anything from a simple action, like filling out a web form, to a complex operation, like crawling an entire website or removing duplicates from a large dataset. +- Actors are programs packaged as Docker images, which accept a well-defined JSON input, perform an action, and optionally produce a well-defined JSON output. -#### macOS/Linux +### Apify Actor directory structure -\`\`\`bash -curl -fsSL https://apify.com/install-cli.sh | bash +\`\`\`text +.actor/ +β”œβ”€β”€ actor.json # Actor config: name, version, env vars, runtime settings +β”œβ”€β”€ input_schema.json # Input validation & Console form definition +β”œβ”€β”€ dataset_schema.json # Dataset schema definition +└── output_schema.json # Specifies where an Actor stores its output +src/ +└── main.js # Actor entry point and orchestrator +storage/ # Local storage (mirrors Cloud during development) +β”œβ”€β”€ datasets/ # Output items (JSON objects) +β”œβ”€β”€ key_value_stores/ # Files, config, INPUT +└── request_queues/ # Pending crawl requests +Dockerfile # Container image definition +AGENTS.md # AI agent instructions (this file) \`\`\` -#### Windows +## Apify CLI -\`\`\`bash -irm https://apify.com/install-cli.ps1 | iex -\`\`\` +### Installation + +- Install Apify CLI only if it is not already installed. +- If Apify CLI is not installed, install it using the following commands: + - macOS/Linux: \`curl -fsSL https://apify.com/install-cli.sh | bash\` + - Windows: \`irm https://apify.com/install-cli.ps1 | iex\` ### Apify CLI Commands From 034689956e5737bbeba3d3de95cfa0f25b737bfa Mon Sep 17 00:00:00 2001 From: patrikbraborec Date: Sun, 26 Oct 2025 11:11:18 +0100 Subject: [PATCH 04/13] docs: fix vale error --- .../actors/development/quick_start/build_with_ai.md | 4 ++-- .../images/{copy-for-llm.png => copy-for-ai.png} | Bin 2 files changed, 2 insertions(+), 2 deletions(-) rename sources/platform/actors/development/quick_start/images/{copy-for-llm.png => copy-for-ai.png} (100%) diff --git a/sources/platform/actors/development/quick_start/build_with_ai.md b/sources/platform/actors/development/quick_start/build_with_ai.md index 72dba259fc..cd78c48e29 100644 --- a/sources/platform/actors/development/quick_start/build_with_ai.md +++ b/sources/platform/actors/development/quick_start/build_with_ai.md @@ -13,7 +13,7 @@ toc_max_heading_level: 4 import { AGENTS_PROMPT } from "@site/src/utils/agents-prompt"; import PromptButton from "@site/src/components/PromptButton"; import InstallMCPButton from "@site/src/components/InstallMCPButton"; -import copyForLlm from "./images/copy-for-llm.png"; +import copyForAI from "./images/copy-for-ai.png"; This guide shows you how to build Actors efficiently with AI coding assistants. You'll learn how to use pre-built instructions, integrate Apify documentation into your AI editor, and apply best practices for AI-assisted development. @@ -76,7 +76,7 @@ claude mcp add apify https://mcp.apify.com/?tools=docs -t http Every page in the Apify documentation has a _Copy for LLM_ button. You can use it to add additional context to your AI assistant, or even open the page in ChatGPT, Claude, or Perplexity and ask additional questions. -Copy for LLM +Copy for LLM ## Use `llms.txt` and `llms-full.txt` diff --git a/sources/platform/actors/development/quick_start/images/copy-for-llm.png b/sources/platform/actors/development/quick_start/images/copy-for-ai.png similarity index 100% rename from sources/platform/actors/development/quick_start/images/copy-for-llm.png rename to sources/platform/actors/development/quick_start/images/copy-for-ai.png From 5707fe5d532934cc70abdd96938bf147377d4f17 Mon Sep 17 00:00:00 2001 From: patrikbraborec Date: Tue, 28 Oct 2025 13:46:05 +0100 Subject: [PATCH 05/13] docs: Change MCP section --- .../development/quick_start/build_with_ai.md | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/sources/platform/actors/development/quick_start/build_with_ai.md b/sources/platform/actors/development/quick_start/build_with_ai.md index cd78c48e29..19567fb44c 100644 --- a/sources/platform/actors/development/quick_start/build_with_ai.md +++ b/sources/platform/actors/development/quick_start/build_with_ai.md @@ -56,21 +56,7 @@ The command above will guide you through Apify Actor initialization, where you s The Apify MCP Server has tools to search and fetch documentation. If you set it up in your AI editor, it will help you improve the generated code by providing additional context to the AI. -Install it by clicking one of the following buttons for your AI editor. - -### Cursor - - - -### VS Code - - - -### Claude Code - -```bash -claude mcp add apify https://mcp.apify.com/?tools=docs -t http -``` +We have prepared the [Apify MCP server configuration](https://mcp.apify.com/), which you can configure for your needs. ## Provide context to assistants From 5c8a3a45732ed83c570da37dab04cb4094aaa10f Mon Sep 17 00:00:00 2001 From: patrikbraborec Date: Tue, 28 Oct 2025 13:49:29 +0100 Subject: [PATCH 06/13] docs: Improve message regarding to MCP --- .../platform/actors/development/quick_start/build_with_ai.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/platform/actors/development/quick_start/build_with_ai.md b/sources/platform/actors/development/quick_start/build_with_ai.md index 19567fb44c..e833ef1fae 100644 --- a/sources/platform/actors/development/quick_start/build_with_ai.md +++ b/sources/platform/actors/development/quick_start/build_with_ai.md @@ -56,8 +56,12 @@ The command above will guide you through Apify Actor initialization, where you s The Apify MCP Server has tools to search and fetch documentation. If you set it up in your AI editor, it will help you improve the generated code by providing additional context to the AI. +:::info Use Apify MCP server configuration + We have prepared the [Apify MCP server configuration](https://mcp.apify.com/), which you can configure for your needs. +::: + ## Provide context to assistants Every page in the Apify documentation has a _Copy for LLM_ button. You can use it to add additional context to your AI assistant, or even open the page in ChatGPT, Claude, or Perplexity and ask additional questions. From 597bdbb5bcdb4e753e81f49ab55a66931701e41c Mon Sep 17 00:00:00 2001 From: Patrik Braborec Date: Wed, 29 Oct 2025 14:44:00 +0100 Subject: [PATCH 07/13] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: JiΕ™Γ­ Spilka Co-authored-by: MichaΕ‚ Olender <92638966+TC-MO@users.noreply.github.com> --- .../actors/development/quick_start/build_with_ai.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sources/platform/actors/development/quick_start/build_with_ai.md b/sources/platform/actors/development/quick_start/build_with_ai.md index e833ef1fae..765e33e267 100644 --- a/sources/platform/actors/development/quick_start/build_with_ai.md +++ b/sources/platform/actors/development/quick_start/build_with_ai.md @@ -1,12 +1,12 @@ --- title: Build with AI sidebar_position: 3 -description: Use pre-built prompts, use Apify docs via llms.txt, and follow best practices to effective vibe coding. +description: Use pre-built prompts, refer to Apify Docs via llms.txt, and follow best practices for effective vibe coding. slug: /actors/development/quick-start/build-with-ai toc_max_heading_level: 4 --- -**Use pre-built prompts, use Apify docs via llms.txt, and follow best practices to build Actors efficiently with AI assistants.** +**Use pre-built prompts, reference Apify Docs via llms.txt, and follow best practices to build Actors efficiently with AI coding assistants.** --- @@ -28,11 +28,11 @@ Use the following prompt in your AI coding assistant ([Cursor](https://www.curso - _Step 1_: Create directory: `mkdir my-new-actor` - _Step 2_: Open the directory in _Cursor_, _Claude Code_, _VS Code with GitHub Copilot_, etc. - _Step 3_: Copy the prompt above and paste it into your AI coding assistant (Agent or Chat) -- _Step 4_: Run it, and develop your first actor with the help of AI πŸŽ‰ +- _Step 4_: Run it, and develop your first actor with the help of AI :::info Start in an AI coding assistant -To maximize efficiency, copy the prompt to Cursor, VS Code with GitHub Copilot, or another AI coding assistant. The AI will follow the guide step-by-step, and you'll avoid copy-pasting from tools like ChatGPT or Claude. +Copy the prompt directly to your AI coding assistant (such as Cursor or VS Code with GitHub Copilot) to maximize efficiency.. The AI will follow the guide step-by-step, and you'll avoid copy-pasting from tools like ChatGPT or Claude. ::: From 362d91a8db8cece9f1a1171a2fb4e5c168b7f4bc Mon Sep 17 00:00:00 2001 From: patrikbraborec Date: Wed, 29 Oct 2025 16:03:55 +0100 Subject: [PATCH 08/13] docs: Fix PR comments --- .../development/quick_start/build_with_ai.md | 20 +++++++++---------- src/components/PromptButton.jsx | 2 +- src/components/PromptButton.module.css | 15 +++++++++++++- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/sources/platform/actors/development/quick_start/build_with_ai.md b/sources/platform/actors/development/quick_start/build_with_ai.md index 765e33e267..5178d41a9c 100644 --- a/sources/platform/actors/development/quick_start/build_with_ai.md +++ b/sources/platform/actors/development/quick_start/build_with_ai.md @@ -15,14 +15,16 @@ import PromptButton from "@site/src/components/PromptButton"; import InstallMCPButton from "@site/src/components/InstallMCPButton"; import copyForAI from "./images/copy-for-ai.png"; -This guide shows you how to build Actors efficiently with AI coding assistants. You'll learn how to use pre-built instructions, integrate Apify documentation into your AI editor, and apply best practices for AI-assisted development. +You will learn several approaches to building Apify Actors with the help of AI coding assistants. This guide includes independent instructions, tools, and best practices that you can use individually or combine together. Each section focuses on a specific part of the process such as prompt usage, Actor templates, Apify MCP server tools, or documentation integration, so you can follow only the parts that fit your development style. ## AI coding assistant instructions -Use the following prompt in your AI coding assistant ([Cursor](https://www.cursor.com/), [Claude Code](https://www.claude.com/product/claude-code), [GitHub Copilot](https://github.com/features/copilot), etc.): +Use the following prompt in your AI coding assistant such as [Cursor](https://www.cursor.com/), [Claude Code](https://www.claude.com/product/claude-code) or [GitHub Copilot](https://github.com/features/copilot): +The prompt guides AI coding assistants such as Cursor, Claude Code or GitHub Copilot to help users 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 and following Apify’s best practices. + ### Quick Start - _Step 1_: Create directory: `mkdir my-new-actor` @@ -30,26 +32,22 @@ Use the following prompt in your AI coding assistant ([Cursor](https://www.curso - _Step 3_: Copy the prompt above and paste it into your AI coding assistant (Agent or Chat) - _Step 4_: Run it, and develop your first actor with the help of AI -:::info Start in an AI coding assistant +:::info Avoid copy-pasting -Copy the prompt directly to your AI coding assistant (such as Cursor or VS Code with GitHub Copilot) to maximize efficiency.. The AI will follow the guide step-by-step, and you'll avoid copy-pasting from tools like ChatGPT or Claude. +The AI will follow the guide step-by-step, and you'll avoid copy-pasting from tools like ChatGPT or Claude. ::: ## Use Actor templates with AGENTS.md -All [Actor Templates](https://apify.com/templates) have AGENTS.md that will help you with AI coding. If you prefer a more traditional approach, run the following command: - -:::info Install Apify CLI - -If you don't have Apify CLI installed, install it first. Check the [installation guide](/cli/docs/installation). - -::: +All [Actor Templates](https://apify.com/templates) have AGENTS.md that will help you with AI coding. You can use the [Apify CLI](/cli/docs) to create Actors from Actor Templates. ```bash apify create ``` +If you do not have Apify CLI installed, see the [installation guide](/cli/docs/installation). + The command above will guide you through Apify Actor initialization, where you select an Actor Template that works for you. The result is an initialized Actor (with AGENTS.md) ready for development. ## Use Apify MCP Server diff --git a/src/components/PromptButton.jsx b/src/components/PromptButton.jsx index be4275055c..b1d01435a0 100644 --- a/src/components/PromptButton.jsx +++ b/src/components/PromptButton.jsx @@ -56,7 +56,7 @@ export default function PromptButton({ prompt = QUICK_START_PROMPT, title = 'Use className={styles['toggle-button']} onClick={togglePrompt} > - {showPrompt ? 'Hide the prompt' : 'Show the prompt'} + {showPrompt ? 'Hide prompt' : 'Show prompt'}