### Setup and Development Environment Source: https://github.com/sanity-io/sanity/blob/main/CONTRIBUTING.md Commands to clone the repository, install dependencies, and start the development server. Ensure Node.js v18+ and pnpm are installed. ```sh git clone git@github.com:sanity-io/sanity.git cd sanity pnpm install pnpm build pnpm dev ``` -------------------------------- ### Getting Started with Sanity Examples Source: https://github.com/sanity-io/sanity/blob/main/examples/README.md Outlines the steps to get started with the Sanity examples, including browsing, copying code, testing, and adapting. ```text 1. **Browse the examples** - Each directory contains detailed README files explaining the implementation 2. **Copy reference code** - Use the examples as starting points for your own projects 3. **Test locally** - Many examples include setup instructions for local development 4. **Adapt and extend** - Modify the examples to fit your specific use case ``` -------------------------------- ### Setup Script-Local Environment File Source: https://github.com/sanity-io/sanity/blob/main/scripts/trigger-triage/README.md Copies the example .env file to create a script-local environment file. This allows Miriad credentials to be scoped specifically to the trigger-triage helper. ```bash cp scripts/trigger-triage/.env.example scripts/trigger-triage/.env ``` -------------------------------- ### Start Auth Test Studio Source: https://github.com/sanity-io/sanity/blob/main/e2e/tests/auth/README.md Command to start the auth test studio. Keep this running while executing tests. ```bash pnpm --filter auth-test-studio dev --port 3340 ``` -------------------------------- ### Install Dependencies Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/stale-content-digest/README.md Install project-level dependencies and then navigate into the function directory to install its specific dependencies. This ensures all necessary packages are available. ```bash npm install dotenv cd functions/stale-content-digest && npm install && cd ../.. ``` -------------------------------- ### Sanity Studio Examples Overview Source: https://github.com/sanity-io/sanity/blob/main/examples/README.md Provides an overview of the different Sanity Studio configurations available in the examples directory, such as for blogs and e-commerce. ```text - [Blog Studio](https://github.com/sanity-io/sanity/tree/main/examples/studios/blog-studio) - Content management for blogs and editorial sites - [E-commerce Studio](https://github.com/sanity-io/sanity/tree/main/examples/studios/ecommerce-studio) - Product catalogs and inventory management - [Clean Studio](https://github.com/sanity-io/sanity/tree/main/examples/studios/clean-studio) - Clean project with no predefined schema types - [Movies Studio](https://github.com/sanity-io/sanity/tree/main/examples/studios/movies-studio) - Movie database with sample content ``` -------------------------------- ### Contributing to Sanity Examples Source: https://github.com/sanity-io/sanity/blob/main/examples/README.md Provides guidance on how to contribute to the Sanity examples, encouraging bug reports and new example submissions. ```text Found a bug or have an idea for a new example? Contributions are welcome! Please check the project's contribution guidelines before submitting pull requests. ``` -------------------------------- ### Install Dependencies Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Installs all project dependencies using pnpm. This command is enforced and requires pnpm v10+. ```bash pnpm install ``` -------------------------------- ### Start the Dev Studio Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Starts the Sanity dev studio locally. This requires browser authentication on first visit and connects to a real Sanity project. ```bash pnpm dev # Starts at http://localhost:3333 ``` -------------------------------- ### Quick Start: Proxy and Test Studio Source: https://github.com/sanity-io/sanity/blob/main/packages/@repo/debug-proxy/README.md Starts the debug proxy and the test Sanity Studio. Use `dev:proxy` for HTTP/2 + TLS or `dev:proxy:http1` for plain HTTP/1.1. ```bash # From the repo root — starts the proxy and the test studio with its # production workspace pointed at the proxy pnpm dev:proxy # studio talks to the proxy over HTTP/2 + TLS (:3051) pnpm dev:proxy:http1 # studio talks to the proxy over plain HTTP/1.1 (:3050) ``` -------------------------------- ### Starting Just the Proxy Source: https://github.com/sanity-io/sanity/blob/main/packages/@repo/debug-proxy/README.md Starts the debug proxy in watch mode or as a one-off process. By default, it serves on `https://localhost:3051`. ```bash # From the repo root pnpm --filter @repo/debug-proxy dev # watch mode pnpm --filter @repo/debug-proxy start # one-off ``` -------------------------------- ### Run Development Studio Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Starts the development studio. Authentication is required, and further details can be found in the documentation. ```bash pnpm dev ``` -------------------------------- ### Sanity Examples Usage Note Source: https://github.com/sanity-io/sanity/blob/main/examples/README.md A note regarding the usage of examples from the Sanity monorepo, emphasizing review and adaptation for production environments. ```text Note: These examples are part of the Sanity monorepo and are designed for reference and learning. For production use, always review and adapt the code to meet your specific requirements and security standards. ``` -------------------------------- ### Install and Trust mkcert CA Source: https://github.com/sanity-io/sanity/blob/main/packages/@repo/debug-proxy/README.md Installs mkcert and adds its locally-trusted CA to your system. This is recommended for seamless certificate handling with the debug proxy. ```bash brew install mkcert && mkcert -install ``` -------------------------------- ### Install Project and Function Dependencies Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/product-mapping/README.md Installs project-level dependencies and specific dependencies for the Sanity function. This ensures all necessary packages are available for the blueprint to run correctly. ```bash npm install cd functions/product-mapping npm install cd ../.. ``` -------------------------------- ### Start Sanity Studio with Debug Proxy Source: https://github.com/sanity-io/sanity/blob/main/packages/@repo/debug-proxy/README.md Starts the Sanity studio with the debug proxy enabled, using HTTP/2 over TLS. This sets the necessary environment variables for the studio to connect to the proxy. ```bash SANITY_STUDIO_USE_DEBUG_PROXY=true pnpm dev ``` -------------------------------- ### Initialize Sanity Blueprint Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/stale-content-digest/README.md Run this command to start the blueprint initialization process for your Sanity project. ```bash npx sanity blueprints init ``` -------------------------------- ### Running the Sanity Dev Studio Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Starts the development studio. Requires Sanity user authentication in the browser and communicates with Sanity API endpoints. ```bash pnpm dev # Starts dev studio at http://localhost:3333 ``` -------------------------------- ### Install Project and Function Dependencies Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/klaviyo-campaign-create/README.md Bash commands to install necessary npm packages for the Sanity project and specifically for the Klaviyo function. This ensures all required libraries are available. ```bash npm install dotenv @portabletext/to-html cd functions/klaviyo-campaign-create npm install cd ../.. ``` -------------------------------- ### Good PR Title Examples Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Examples of correctly formatted PR titles that follow the conventional commit structure. ```text fix(groq): resolve CJS type export issue ``` ```text feat(form): add new array input component ``` ```text chore(deps): update dependencies ``` -------------------------------- ### Install Dependencies Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/social-media-crosspost/README.md Commands to install necessary dependencies in the project root and the specific functions directory. ```bash npm install dotenv cd functions/social-media-crosspost npm install ``` -------------------------------- ### Initialize Sanity Blueprint Example Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/klaviyo-campaign-create/README.md Commands to initialize or add the Klaviyo campaign create blueprint to a Sanity project. This sets up the necessary files and configurations for the blueprint. ```bash npx sanity blueprints init --example klaviyo-campaign-create ``` ```bash npx sanity blueprints add function --example klaviyo-campaign-create ``` -------------------------------- ### Sanity Functions Key Files Source: https://github.com/sanity-io/sanity/blob/main/examples/README.md Lists and describes the essential files for Sanity Functions examples, including configuration, bundling, and discovery. ```text - `sanity.blueprint.ts` - Automatically discovers and configures all function examples for easy testing - `package.json` - Shared dependencies for all function examples - `vite.config.js` - Build configuration for bundling functions ``` -------------------------------- ### Build and Run Test Studio with Vite DevTools Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Builds the test studio with Vite DevTools enabled and starts the dev server, allowing inspection of the build output. ```bash pnpm devtools:test-studio ``` -------------------------------- ### Install Project Dependencies (Bash) Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/auto-summary/README.md This command installs all the necessary Node.js dependencies for your Sanity project, including those required for the auto-summary function. Run this from the root of your project. ```bash npm install ``` -------------------------------- ### Install Dependencies and Deploy Schema Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/social-media-crosspost/README.md Commands to install necessary UI dependencies and deploy the updated schema configuration to the Sanity project. ```bash cd studio npm install @sanity/ui cd studio npx sanity schema deploy ``` -------------------------------- ### Install GROQ dependency Source: https://github.com/sanity-io/sanity/blob/main/packages/groq/README.md The command to install the groq package via npm for use in a JavaScript or TypeScript project. ```bash npm install --save groq ``` -------------------------------- ### Initialize Sanity Blueprints Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/mastodon-post/README.md Commands to initialize the blueprint system and add the mastodon-post function example to your Sanity project. ```bash npx sanity blueprints init npx sanity blueprints add function --example mastodon-post ``` -------------------------------- ### Sanity Functions Directory Structure Source: https://github.com/sanity-io/sanity/blob/main/examples/README.md Illustrates the organization of Sanity Functions examples within the project, highlighting key files and subdirectories. ```text examples/ ├── functions/ # Sanity Functions examples └── studios/ # Studio configuration examples ``` -------------------------------- ### Start Sanity Functions Development Server (Bash) Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/auto-summary/README.md This command starts the Sanity development server in interactive mode, allowing you to test and debug your Sanity Functions, including the auto-summary function, in real-time. ```bash npx sanity functions dev ``` -------------------------------- ### Integrate Scenario with SSE Proxy Source: https://github.com/sanity-io/sanity/blob/main/packages/@repo/debug-proxy/README.md Shows how to wire up a custom scenario into the SSE proxy listener route. This example composes the `truncateMutations` scenario with a 10% probability. ```typescript {match: isListenEndpoint(), handler: createSSEProxy((events$) => events$.pipe(truncateMutations(0.1)))} ``` -------------------------------- ### Customize Created Document Structure Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/product-mapping/README.md Example of using the Sanity client to create a new document with custom fields and references. ```typescript const newProductMap = await client.create({ _id: productMapId, _type: 'productMap', id: productMapName, products: [{_key: `product-${_id}`, _ref: _id, _type: 'reference'}], description: `Product map for ${productMapName}`, careInstructions: [], // Add custom fields category: 'auto-generated', createdAt: new Date().toISOString(), }) ``` -------------------------------- ### Sanity Project Structure Overview Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md This tree structure illustrates the organization of the Sanity monorepo, including core packages, development studios, testing directories, and examples. ```bash sanity/ ├── packages/ │ ├── sanity/ # Main Sanity studio package │ ├── @sanity/ # Scoped packages (cli, types, schema, etc.) │ └── @repo/ # Internal tooling (test-config, tsconfig, etc.) ├── dev/ # Development studios for testing │ └── test-studio/ # Primary dev studio (pnpm dev runs this) ├── e2e/ # End-to-end Playwright tests ├── perf/ # Performance testing └── examples/ # Example studios ``` -------------------------------- ### Local Environment: GitHub Token Source: https://github.com/sanity-io/sanity/blob/main/scripts/trigger-triage/README.md Example of setting the GITHUB_TOKEN for local runs when testing against private repositories or to avoid GitHub API rate limits. The script automatically loads local .env files. ```bash GITHUB_TOKEN=ghp_example pnpm issue-triage --dry-run https://github.com/sanity-io/sanity/issues/725 ``` -------------------------------- ### Initialize Sanity Blueprints (Bash) Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/auto-summary/README.md This command initializes Sanity Blueprints in your project if you haven't already. It guides you through selecting your organization and Sanity studio. ```bash npx sanity blueprints init ``` -------------------------------- ### Run Specific Test Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md To get more detailed output for a specific test failure, use this command, replacing `` with the actual test identifier. Ensure you have built the project first. ```bash pnpm test -- ``` -------------------------------- ### Router utility methods for 404s and base paths Source: https://github.com/sanity-io/sanity/blob/main/packages/sanity/src/router/README.md Provides examples for checking invalid paths using isNotFound and managing base path redirects using isRoot and getRedirectBase. ```javascript const router = route('/pages/:page') router.isNotFound('/some/invalid/path') // Base path redirect logic const redirectTo = router.getRedirectBase(location.pathname) if (redirectTo) { history.replaceState(null, null, redirectTo) } ``` -------------------------------- ### Initialize and Add Auto-Changelog Blueprint Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/auto-changelog/README.md These bash commands guide you through initializing Sanity blueprints and adding the 'auto-changelog' example function. This sets up the necessary project structure and configuration for the function. ```bash npx sanity blueprints init npx sanity blueprints add function --example auto-changelog ``` -------------------------------- ### Create Project and Bootstrap Moviedb Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/stale-content-digest/README.md Use the Sanity CLI to initialize a new project with the moviedb template. This command sets up the project structure and imports a sample dataset. ```bash mkdir movies-project cd movies-project npx sanity init --template moviedb --import-dataset --output-path=studio ``` -------------------------------- ### Build and Run E2E Tests Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Commands to build the E2E test studio and then execute the End-to-End tests. An optional flag is available for interactive mode. ```bash pnpm e2e:build # Build E2E studio pnpm test:e2e # Run E2E tests pnpm test:e2e --ui # Interactive mode ``` -------------------------------- ### Install Dependencies for Sanity Blueprint Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/bluesky-post/README.md Command to install the 'dotenv' package, which is required for loading environment variables in the Sanity blueprint configuration. ```bash npm install dotenv ``` -------------------------------- ### Bad PR Title Examples Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Examples of incorrectly formatted PR titles that will fail CI validation. These illustrate common mistakes like using backticks or incorrect casing. ```text feat(groq): add `types` condition # no backticks allowed ``` ```text Fix(cli): Handle missing config # type must be lowercase, description must start lowercase ``` ```text added new feature # missing type and scope ``` -------------------------------- ### Add Auto-Summary Example Blueprint (Bash) Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/auto-summary/README.md This command adds the 'auto-summary' example blueprint to your Sanity project, setting up the necessary function files and configurations. ```bash npx sanity blueprints add function --example auto-summary ``` -------------------------------- ### Test Sanity Functions via CLI Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/product-mapping/README.md Commands to test Sanity functions using the CLI. These examples demonstrate creating test documents, querying existing data, and executing the 'product-mapping' function against specific datasets. ```bash cd studio cat > test-product.json << EOF { "_type": "product", "title": "Test Product with Tags", "store": { "tags": ["sanity-parent-summer-collection", "sanity-color-blue", "cotton", "t-shirt"], "slug": { "current": "test-product-tags" } } } EOF npx sanity documents create test-product.json --replace cd .. npx sanity functions test product-mapping --file studio/test-product.json --dataset production --with-user-token ``` ```bash cd studio npx sanity documents query "*[_type == 'product'][0]" > ../real-product.json cd .. npx sanity functions test product-mapping --file real-product.json --dataset production --with-user-token ``` ```bash npx sanity functions dev ``` ```bash cd studio REAL_DOC_ID=$(npx sanity documents query "*[_type == 'product'][0]._id" | tr -d '"') cd .. cat > test-custom-product.json << EOF { "_type": "product", "_id": "$REAL_DOC_ID", "title": "Custom Test Product", "store": { "tags": ["sanity-parent-winter-collection", "sanity-color-red", "wool", "sweater"], "slug": { "current": "custom-test-product" } } } EOF npx sanity functions test product-mapping --file test-custom-product.json --dataset production --with-user-token ``` ```bash cd studio npx sanity documents query "*[_type == 'product' && defined(store.tags)][0]" > ../test-real-product.json cd .. npx sanity functions test product-mapping --file test-real-product.json --dataset production --with-user-token ``` -------------------------------- ### Clean and Bootstrap Project Dependencies Source: https://github.com/sanity-io/sanity/blob/main/CONTRIBUTING.md Use this command to resolve build issues by cleaning all node_modules, reinstalling dependencies, and building ES6 code to ES5. ```sh pnpm clean && pnpm clean:deps pnpm bootstrap ``` -------------------------------- ### Add Brand Voice Validator Example (Bash) Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/brand-voice-validator/README.md This command adds the 'brand-voice-validator' example function to your Sanity project using the blueprints CLI. Ensure you have initialized blueprints first. ```bash npx sanity blueprints add function --example brand-voice-validator ``` -------------------------------- ### Build All Packages Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Builds all packages within the monorepo. This is a required step before running tests. ```bash pnpm build ``` -------------------------------- ### Install Project and Function Dependencies (Bash) Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/stale-products-analysis/README.md Bash commands to install npm dependencies for the project root and specifically for the Sanity function. This ensures all required packages are available. ```bash npm install npm install @sanity/functions cd functions/stale-products-analysis npm install cd ../.. ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/stale-content-digest/README.md Create a .env file in your project root to store configuration variables for the Sanity function and Slack integration. Ensure SLACK_OAUTH_TOKEN and SLACK_CHANNEL are correctly set. ```env PROJECT_ID=your-sanity-project-id DATASET=production SLACK_OAUTH_TOKEN=xoxb-your-bot-token SLACK_CHANNEL=#your-test-channel DAYS_SINCE=0 ``` -------------------------------- ### Start Sanity Interactive Development Mode (Bash) Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/slack-notify/README.md Starts the Sanity development server in interactive mode, allowing for real-time testing of functions. This mode requires the Slack OAuth token to be set as an environment variable. ```bash SLACK_OAUTH_TOKEN=slack-OAuth-token npx sanity functions dev ``` -------------------------------- ### Run All Auth Tests Source: https://github.com/sanity-io/sanity/blob/main/e2e/tests/auth/README.md Command to execute all authentication-related end-to-end tests. ```bash pnpm --filter e2e test:auth ``` -------------------------------- ### Run Unit Tests with Vitest Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Commands for running Vitest unit tests. Includes options for watch mode and updating snapshots. Tests may require a prior build. ```bash pnpm test # Run all tests pnpm test -- --watch # Watch mode pnpm test -- -u # Update snapshots pnpm test -- --project=sanity # Run specific project ``` ```bash pnpm build && pnpm test ``` -------------------------------- ### Configure Environment Variables for E2E Tests Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Set up necessary environment variables in .env.local for running End-to-End tests. These include authentication tokens and project details. ```bash SANITY_E2E_SESSION_TOKEN= SANITY_E2E_PROJECT_ID= SANITY_E2E_DATASET= ``` -------------------------------- ### Add Stale Content Digest Function Blueprint Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/stale-content-digest/README.md This command adds the 'stale-content-digest' function example to your Sanity project's blueprints. ```bash npx sanity blueprints add function --example stale-content-digest ``` -------------------------------- ### Run Tests Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Executes all unit tests for the project. Tests are sharded in CI. ```bash pnpm test ``` -------------------------------- ### Build Studio URL with Auth Token Source: https://github.com/sanity-io/sanity/blob/main/AGENTS.md Constructs a URL to access the Sanity dev studio with authentication. Ensure the STUDIO_AUTH_TOKEN environment variable is set. ```javascript node -e "console.log('http://localhost:3333/test#token=' + encodeURIComponent(process.env.STUDIO_AUTH_TOKEN))" ``` -------------------------------- ### Environment Variable Configuration Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/social-media-crosspost/README.md Example structure for the .env file required to store platform-specific API credentials. ```env TWITTER_ACCESS_TOKEN_KEY=your-access-token TWITTER_ACCESS_TOKEN_SECRET=your-access-secret TWITTER_API_CONSUMER_KEY=your-consumer-key TWITTER_API_CONSUMER_SECRET=your-consumer-secret MASTODON_ACCESS_TOKEN=your-access-token MASTODON_HOST=mastodon.social BLUESKY_IDENTIFIER=yourname.bsky.social BLUESKY_PASSWORD=xxxx-xxxx-xxxx-xxxx BLUESKY_HOST=bsky.social LINKEDIN_ACCESS_TOKEN=your-linkedin-token DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... TELEGRAM_BOT_TOKEN=your-bot-token TELEGRAM_CHAT_ID=your-chat-id SLACK_BOT_TOKEN=xoxb-your-bot-token SLACK_CHANNEL=your-channel-id DEVTO_API_KEY=your-api-key ``` -------------------------------- ### Promote Sanity Blueprint Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/stale-content-digest/README.md Promote your stack to organization scope. This is a one-way operation. ```bash npx sanity blueprints promote ``` -------------------------------- ### Edit variant definition conditions Source: https://github.com/sanity-io/sanity/blob/main/packages/sanity/src/core/variants/ACTIONS.md Example of editing only the conditions of a variant definition. This uses the `set` operation within the patch to update the `conditions` field. ```typescript await client.action({ actionType: 'sanity.action.variant.definition.edit', variantId: 'Ab12cd34', patch: { set: {conditions: {audience: 'loyal'}}, }, }) ``` -------------------------------- ### Debug Sanity Function Logs Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/product-mapping/README.md Example of logging statements used within a Sanity function to track execution flow and data processing results. ```typescript console.log('👋 Your Sanity Function was called at', new Date().toISOString()) console.log('🏷️ Processing tags for product:', _id, 'Tags:', tags) console.log('✅ Created productMap:', productMapName, 'with ID:', newProductMap._id) console.log('✅ Created colorVariant:', colorName, 'with ID:', newColorVariant._id) ``` -------------------------------- ### Test Sanity Functions with Custom Data Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/klaviyo-campaign-create/README.md Demonstrates how to create a local JSON file representing a document and execute a function against it using the Sanity CLI. ```bash cd studio REAL_DOC_ID=$(npx sanity documents query "*[_type == 'emails'][0]._id" | tr -d '"') cd .. cat > test-custom-data.json << EOF { "_type": "emails", "_id": "$REAL_DOC_ID", "title": "Custom Test Email Campaign", "body": [ { "_type": "block", "children": [{"_type": "span", "text": "Custom test content"}] } ], "status": "inprogress" } EOF npx sanity functions test klaviyo-campaign-create --file test-custom-data.json --dataset production --with-user-token ``` -------------------------------- ### Debug Sanity Function Execution Source: https://github.com/sanity-io/sanity/blob/main/examples/functions/klaviyo-campaign-create/README.md Example of logging function execution steps to the console for monitoring operations like API calls and template creation. ```typescript console.log('👋 Marketing Campaign Function called at', new Date().toISOString()) console.log('✅ Created Klaviyo template:', template.data.id) console.log('✅ Created Klaviyo campaign:', campaign.data.id) ```