diff --git a/.gitignore b/.gitignore index 70bd042df..d5727686d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ site/resources/ __checks__/screenshots .vercel checkly-github-report.md +CLAUDE.md \ No newline at end of file diff --git a/site/assets/guides/images/claude-monitoring-01.png b/site/assets/guides/images/claude-monitoring-01.png new file mode 100644 index 000000000..8e2bc16b3 Binary files /dev/null and b/site/assets/guides/images/claude-monitoring-01.png differ diff --git a/site/assets/guides/images/claude-monitoring-02.png b/site/assets/guides/images/claude-monitoring-02.png new file mode 100644 index 000000000..a37b6daa6 Binary files /dev/null and b/site/assets/guides/images/claude-monitoring-02.png differ diff --git a/site/assets/guides/images/claude-monitoring-03.png b/site/assets/guides/images/claude-monitoring-03.png new file mode 100644 index 000000000..dfb4d70e7 Binary files /dev/null and b/site/assets/guides/images/claude-monitoring-03.png differ diff --git a/site/assets/guides/images/claude-monitoring-04.png b/site/assets/guides/images/claude-monitoring-04.png new file mode 100644 index 000000000..ef62f7fd9 Binary files /dev/null and b/site/assets/guides/images/claude-monitoring-04.png differ diff --git a/site/assets/guides/images/claude-monitoring-05.png b/site/assets/guides/images/claude-monitoring-05.png new file mode 100644 index 000000000..635a3f52c Binary files /dev/null and b/site/assets/guides/images/claude-monitoring-05.png differ diff --git a/site/assets/guides/images/monitor-many-urls-01.png b/site/assets/guides/images/monitor-many-urls-01.png new file mode 100644 index 000000000..d94e48dfa Binary files /dev/null and b/site/assets/guides/images/monitor-many-urls-01.png differ diff --git a/site/assets/guides/images/monitor-many-urls-02.png b/site/assets/guides/images/monitor-many-urls-02.png new file mode 100644 index 000000000..bf55a4d21 Binary files /dev/null and b/site/assets/guides/images/monitor-many-urls-02.png differ diff --git a/site/assets/guides/images/monitor-many-urls-03.png b/site/assets/guides/images/monitor-many-urls-03.png new file mode 100644 index 000000000..00297a74b Binary files /dev/null and b/site/assets/guides/images/monitor-many-urls-03.png differ diff --git a/site/content/docs/ai/use-checkly-with-ai-ide.md b/site/content/docs/ai/use-checkly-with-ai-ide.md index 281410e58..84deb1e73 100644 --- a/site/content/docs/ai/use-checkly-with-ai-ide.md +++ b/site/content/docs/ai/use-checkly-with-ai-ide.md @@ -10,6 +10,7 @@ menu: ## Docs +You can index our docs pages in your IDE to leverage better code generation results. To do so, follow the guides for your IDE of choice: You can index our docs pages in your IDE to leverage better code generation results. To do so, follow the guides for your IDE of choice: Make sure to index the following url: @@ -35,6 +36,8 @@ of our docs pages in plain text format. You can use this file to index our docs We prepared a first set of AI rules which you can use to teach your AI IDE of choice on how to generate code for Checkly. Go into the root of your IDE's workspace and download the rules according to your IDE's config parameters. When asking questions about Checkly, manually add the downloaded rules files to your prompt. +Go into the root of your IDE's workspace and download the rules according to your IDE's config parameters. +When asking questions about Checkly, manually add the downloaded rules files to your prompt. ### GitHub Copilot @@ -122,7 +125,7 @@ API Checks, Browser checks, Multistep checks and all other constructs. {{< tab "Mac and Linux" >}} ```bash -mkdir \p .claude && +mkdir -p .claude && curl -o .claude/checkly.rules.md https://www.checklyhq.com/docs/ai/checkly.rules.md -L echo "- examine checkly.rules.md for code generation rules" >> .claude/CLAUDE.md ``` diff --git a/site/content/guides/claude-code-monitoring.md b/site/content/guides/claude-code-monitoring.md new file mode 100644 index 000000000..0a27acb20 --- /dev/null +++ b/site/content/guides/claude-code-monitoring.md @@ -0,0 +1,299 @@ +--- +title: Add in Depth Monitoring With Checkly and Claude Code +description: >- + By integrating AI into your development workflow, you can generate valid Checkly constructs—including URL monitors and Playwright-based browser checks—with minimal effort. +author: Nočnica Mellifera +avatar: 'images/avatars/nica-mellifera.png' +tags: + - AI +--- +AI-assisted coding promises to massively upgrade developer productivity, and with Checkly’s model of [Monitoring as Code](https://www.checklyhq.com/blog/monitoring-as-code-in-your-sdlc/), you can create monitoring coverage for all your services in minutes instead of days. This guide will show you how to create an AI development environment that lets you create and deploy all types of Checkly monitoring. + +## Setup + +If you haven’t already, start by [installing the Checkly CLI](https://www.checklyhq.com/docs/cli/installation/), then create a repository that will be the ‘project’ that contains all your Checkly monitors managed as code. If you don’t already have a project, create one with: + +```bash +npm create checkly@latest +``` + +Next, install [Claude Code](https://www.anthropic.com/claude-code) globally with + +```bash +npm install -g @anthropic-ai/claude-code +``` + +and from the root folder of your project and start Code with the `claude` command. + +You’ll be prompted to sign in to or sign up for an Anthropic account. + +I recommend using [the Visual Studio Code plugin for Claude](https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code), which will make it easier to provide Claude Code with the VS Code file browser context (the VS Code plugin does a lot more than just context, this is just the most convenient feature we’ll use for this tutorial). + +### Add the Playwright MCP + +You can give Claude Code access to a browser by adding the [Playwright MCP](https://github.com/microsoft/playwright-mcp) to your local configuration with + +```bash +claude mcp add playwright npx @playwright/mcp@latest +``` +This will let us ask Claude Code to do things like crawling a particular website and acting on what it finds by opening the site in a browser. + +## Give Claude Code Some Context +Everything we write into the CLI interface is part of a 'prompt,' and by default, Claude Code will add a bit of information to what we submit as 'context' on that prompt. Ideally, our requests written into Claude Code would include context about our specific project: its structure, language, and even its purpose. Because of the `npm create` command we ran above, our folder already has a boilerplate version of a Checkly project. We can't feed in all of these files as context, but we can add a summary of our whole project as context by opening Claude Code and running the command: + +> /init + +Claude Code will scan the whole project, write a summary, and then store that summary in a local CLAUDE.md file. Claude Code will read that file and add it to our prompt every time it's run within this project from now on. + +Let's add a bit more to this context, we want test files that make sense as a [Checkly construct](https://www.checklyhq.com/docs/cli/constructs-reference/). Let’s add [Checkly’s AI rules file](https://www.checklyhq.com/docs/ai//use-checkly-with-ai-ide/#claude-code) to our [CLAUDE.md](http://CLAUDE.md) context file: + +```bash +mkdir -p .claude && +curl -o .claude/checkly.rules.md https://www.checklyhq.com/docs/ai/checkly.rules.md -L +echo "- examine checkly.rules.md for code generation rules" >> .claude/CLAUDE.md +``` + +After this you’ll need to exit and restart Claude Code for it to pick up changes to our context file. + +## Create new URL Monitors + +We’ll start with something easy. A URL monitor that will check an HTTP endpoint and alert if it doesn’t receive the right status code. With the context set from the section above, try a command like: + +> Create a new URL pinger for the site [https://danube-webshop.herokuapp.com/](https://danube-webshop.herokuapp.com/) that runs every five minutes and doesn’t follow redirects. + +After a few seconds, Claude Code will produce this: + +```ts +import { Frequency, UrlMonitor, UrlAssertionBuilder } from 'checkly/constructs' + +new UrlMonitor('danube-web-shop-pinger', { + frequency: Frequency.EVERY_5M, + name: 'Danube Web Shop Pinger', + activated: true, + request: { + url: 'https://danube-web.shop/', + skipSSL: false, + followRedirects: false, + assertions: [ + UrlAssertionBuilder.statusCode().equals(200), + ] + } +}) +``` + +While we’re writing this simplest of monitors, it’s worth testing the limits of Claude Code’s context for writing valid Checkly configuration. One thing I tested while writing this article was whether picking the wrong prompt would result in invalid Checkly construct code. The Frequency class here doesn’t accept arbitrary values, so I wondered what would happen since the [source file for Frequency](https://github.com/checkly/checkly-cli/blob/main/packages/cli/src/constructs/frequency.ts) won’t be part of Claude’s context. I tried requesting a check that ran “every 17 seconds” and Claude Code prompted me to run a `find` on the project to identify valid values for `frequency`. In the end, Claude Code did create valid code with this note in the process feed. + +![Feedback on the terminal](/guides/images/claude-monitoring-01.png) + +## Create Playwright Synthetics Checks With Claude Code + +It would be nice to have Claude Code automatically create the Playwright scripts we need to test our site's features. However, without careful controls, any 2025-era coding agent tends to write Playwright code that is either out of date or doesn’t follow best practices. The best way to get high-quality output is through some prompt engineering and careful provision of context. + +### 1. Start With Playwright Codegen + +We can capture our behavior in the browser to script a test with [Playwright Codegen](https://www.checklyhq.com/learn/playwright/codegen/), available either as a standalone utility, browser plugin, or VS Code plugin. Once [Codegen is set up](https://www.checklyhq.com/learn/playwright/codegen/), start recording and record the following: + +- Navigate to your homepage. +- Browse through multiple pages. +- Assert the visibility of 1-2 page elements. + +Once you’re done, copy the resulting code and create a file in `/__checks__` called `homepage-browse.spec.ts`. It should look something like this: + +```ts {title="homepage-browse.spec.ts"} +import { test, expect } from '@playwright/test'; + +test('test', async ({ page }) => { + await page.goto('https://danube-web.shop/'); + await page.getByText('Haben oder haben').click(); + await page.getByRole('button', { name: 'Add to cart' }).click(); + await page.getByRole('link').click(); + await page.locator('a').filter({ hasText: 'Fantasy' }).click(); + await expect(page.getByText('The Polar Turtle')).toBeVisible(); + await expect(page.getByText('$9').first()).toBeVisible(); +}); +``` + +Lets make sure our script is valid by running this test: + +```bash +npx checkly test homepage-browse +``` + +*Without an exact file path, the `checkly test` command will run any test that matches this pattern.* + +and making sure the test passes. + +![Feedback on the terminal](/guides/images/claude-monitoring-02.png) + +*Like always with the `checkly test` command, this test isn’t running from my laptop but rather Checkly's global monitoring infrastructure.* + +Next we’ll want to create a `.check.ts` file for this browser check, which sets some check-specific settings and assigns the check’s logical ID. + +```ts {title="homepage-browse.check.ts"} +import { AlertChannel, AlertEscalationBuilder, BrowserCheck, RetryStrategyBuilder } from 'checkly/constructs' + +new BrowserCheck('browse-danube-homepage-v1', { + name: 'Browse Danube Homepage', + code: { + entrypoint: './homepage-browse.spec.ts', + }, + activated: true, + muted: false, + shouldFail: false, + locations: [ + 'us-east-1', + 'us-west-1', + ], + frequency: 5, + alertEscalationPolicy: AlertEscalationBuilder.runBasedEscalation(1, { + amount: 0, + interval: 5, + }, { + enabled: false, + percentage: 10, + }), + retryStrategy: RetryStrategyBuilder.linearStrategy({ + baseBackoffSeconds: 60, + maxRetries: 2, + maxDurationSeconds: 600, + sameRegion: true, + }), + runParallel: true, +}) +``` + +These settings are all optional and any not specified will default back to the account or project default, but it’s good to include them as our model. + +If we want to check our formatting, we can run the `checkly deploy` command with the preview flag: + +```bash +npx checkly deploy -p +``` + +### 2. Add our new Check to Claude’s Context + +With these checks created, add their references to Claude’s context by giving Claude Code the prompt: + +> update my [CLAUDE.md](http://claude.md/) file with the new code in /__checks__ +> + +Let’s take one additional step, add the following lines to your updated [CLAUDE.md](http://CLAUDE.md) file: + +```markdown +- When writing Playwright, don't set locators equal to const, rather just perform expect tests directly on locators +- When writing a spec.ts file, don't use locators based on CSS class +``` + +Pro tip: from the Claude Code prompt just hit octothorp ‘#’ to add to Claude’s memory. + +### 3. Use Claude Code to create new Checks + +Now that we’ve got a working test and config, let’s let Claude Code create a check for us: + +> Create a new browser check for [https://danube-web.shop/](https://danube-web.shop/) that clicks on a single button then checks the visibility of 10 different elements on +the page +> + +The importance of step 1 above is apparent during the output from this task, as Claude Code examines the known good. + +![Feedback on the terminal](/guides/images/claude-monitoring-03.png) + +In order to scan the URL provided, Claude Code will confirm that it can use the Playwright MCP to open a browser and access the site. The result is a nice clean test written to the spec: + +```ts {title="item-visibility.spec.ts"} +import { test, expect } from '@playwright/test'; + +test('item visibility check', async ({ page }) => { + await page.goto('https://danube-web.shop/'); + + // Click on the "Books" heading + await page.getByRole('heading', { name: 'Books', exact: true }).click(); + + // Check visibility of 10 different items on the page + await expect(page.getByText('Haben oder haben')).toBeVisible(); + // removed 6 more for readability + await expect(page.getByText('Fantasy')).toBeVisible(); + await expect(page.getByText('$9.95').first()).toBeVisible(); + await expect(page.getByRole('heading', { name: 'Top sellers' })).toBeVisible(); +}); +``` + +Claude Code will confirm before creating the check and spec files with the configuration and script, respectively. + +You can prompt for multiple checks at the same time, as the output is relatively token-efficient. As you can imagine, this unlocks the creation of a large number of synthetic monitors relatively quickly. Another use case that may be useful for larger projects, try prompting Claude Code with something like: + + +> update every `.check.ts` file for a check that touches [danube-web.shop](http://danube-web.shop/), and change +> the frequency to every 30 minutes. +> + +Not only did this request work, but I even got sensible feedback about the checks that currently had no frequency setting: + +```bash + The url.check.ts and api.check.ts files don't have individual frequency settings - + they inherit the default frequency from the project configuration in + checkly.config.ts. +``` + +Once we’re done creating new checks, it’s time to run them all with: + +```bash +npx checkly test +``` + +When I ran a number of generated tests, the only issue I ran into was a failure with the message: `Error: expect.toBeVisible: Error: strict mode violation: getByText('Crime & Thrillers') resolved to 2 elements:`. As the error message implies, the issue is that this locator: + +```ts + await expect(page.getByText('Fantasy')).toBeVisible(); +``` + +Found multiple results on the page. There are a number of ways to fix this with Claude Code, we could prompt Claude Code with: + +> revise locators in item-visibility.spec.ts to look at only the first result +> + +This would change every locator, which may or may not be what you want! You could also paste in the error message to Claude and ask it to fix the script. Whatever route you take the result will be an edit to: + +```ts + await expect(page.getByText('Fantasy').first()).toBeVisible(); +``` + +If you’re having trouble reading the generated tests, take a look at [Checkly’s Playwright documentation](https://www.checklyhq.com/learn/playwright/). Once Claude Code added a single `.first()` to my check, everything was passing: + +![Feedback on the terminal](/guides/images/claude-monitoring-04.png) + +## Deploy With the Checkly CLI + +In our example, we want to deploy several checks at once, so it’s worth checking whether the configuration is properly formatted before deployment. Many problems would have been revealed while running `test` but if, for example, the [logical IDs](https://www.checklyhq.com/docs/cli/constructs-reference/#synthetic-checks) of current and existing checks are colliding, we’ll need to run `deploy` to detect that. Run the `deploy` command with the `-p` preview flag: + +```bash +npx checkly deploy -p +``` + +This command won’t deploy anything, just parse our project and show us what will be created when we run the command without the preview flag. + +![Feedback on the terminal](/guides/images/claude-monitoring-05.png) +*An example screenshot of the preview generated by the `npx checkly deploy -p` command. Checks with new logical IDs are listed as created, existing checks are listed as 'Update and Unchanged' and any checks which used to be associated with this project and arent present in our folder will be deleted* + +If you’re getting strange results from a preview of `deploy` and you’re not sure why, it might be time to get in touch with the Checkly team, [join our Slack](https://checklyhq.com/slack) for deployment advice! + +Once we’re happy with what will be deployed, it’s time to run `npx checkly deploy` and create our checks! + +## Conclusion + +AI-assisted coding tools like Claude Code can significantly accelerate the creation and deployment of monitoring checks with Checkly’s Monitoring as Code approach. By integrating AI into your development workflow, you can generate valid Checkly constructs—including URL monitors and Playwright-based browser checks—with minimal effort. One of the superpowers that an AI workflow can unlock is the *mass updating of many files in your project.* Updating a large number of test files can go way faster with the help of Claude Code. + +While AI can handle much of the boilerplate work, human oversight remains essential for ensuring best practices, refining assertions, and maintaining high-quality monitoring scripts. By combining AI efficiency with developer expertise, teams can achieve comprehensive monitoring coverage in minutes rather than days. + +## Further Reading + +To learn more about Checkly’s capabilities, explore these resources: + +- [Checkly CLI Documentation](https://www.checklyhq.com/docs/cli/) – Learn how to manage checks as code right from your command line. +- [Playwright Testing Guide](https://www.checklyhq.com/learn/playwright/) – Best practices for writing reliable browser checks. +- [What is monitoring as code?](https://www.checklyhq.com/guides/monitoring-as-code/) — A comprehensive guide to infrastructure-as-code principles for monitoring. +- [Checkly Community Slack](https://checklyhq.com/slack) – Join discussions and get support from the Checkly team and other users. + +For more tutorials and advanced use cases, visit the [Checkly YouTube channel](https://www.youtube.com/@ChecklyHQ), where you can see great tutorials like this guide to the Playwright MCP server: + +{{< youtube id="MIlcVo1x3Is" title="Generating Playwright Tests With AI: Let's Try the New Playwright MCP Server!">}} \ No newline at end of file diff --git a/site/content/guides/monitor-many-urls.md b/site/content/guides/monitor-many-urls.md new file mode 100644 index 000000000..5f2e78b4b --- /dev/null +++ b/site/content/guides/monitor-many-urls.md @@ -0,0 +1,204 @@ +--- +title: Monitor 500 pages in 2 minutes with Checkly +displayTitle: Monitor 500 pages in 2 minutes with Checkly +description: >- + By leveraging arrays, sitemap parsing, and dynamic monitor creation, you can ensure comprehensive coverage of your website, API routes, and third-party services—all from a single configuration file. +author: Nočnica Mellifera +avatar: 'images/avatars/nica-mellifera.png' +tags: + - FAQ +--- + +Checkly’s model of [Monitoring as Code](https://www.checklyhq.com/guides/getting-started-with-monitoring-as-code/) lets you create site monitors right from your IDE. With the recent release of uptime monitoring, we have the ability to monitor every single URL, API route, and even third party service that makes up our product. We don’t want to write out dozens or hundreds of files for all this monitoring coverage. + +If this is your first interaction with Monitoring as Code, check out our guide on [creating URL Monitors with Monitoring as Code](https://www.checklyhq.com/guides/url-monitoring/). That guide is all you need to create a project with a first monitor. + +## tl;dr Here’s how to create lots of monitors at once + +Here’s a single file that will create URL monitors from an array: + +```ts +//urlArrayMonitors.check.ts +//this will create URL monitors in your Checkly dashboard + +import { Frequency, UrlMonitor, UrlAssertionBuilder } from 'checkly/constructs' + +//just two URLs in this example, add as many as you want +const sitemapUrls = [ + 'https://docs.anthropic.com/de/api/admin-api/workspace_members/get-workspace-member', + 'https://docs.anthropic.com/de/api/admin-api/workspace_members/list-workspace-members' +] + +//create paths and friendly names for each monitor +sitemapUrls.forEach((url, index) => { + const urlPath = new URL(url).pathname.replace(/\//g, '-').replace(/^-+|-+$/g, '') || 'root' + const monitorId = `checkly-${urlPath}-ping` + const monitorName = `${urlPath.replace(/-/g, ' ')} pinger` + +//create each monitor with a five minute interval + new UrlMonitor(monitorId, { + frequency: Frequency.EVERY_5M, + name: monitorName, + activated: true, + request: { + url: url, + skipSSL: false, + followRedirects: true, + assertions: [ + UrlAssertionBuilder.statusCode().equals(200), + ] + } + }) +}) +``` + +This takes an array of URLs and creates a new monitor with a unique ID and name. We can test run these tests with `npx checkly test` and both monitors will run in our CLI’s default region. + +![A terminal](/guides/images/monitor-many-urls-01.png) + +You can add as many URLs as you’d like to the array and get them monitored at the settings listed. Some lines from this file are worth noting: + +```ts +const urlPath = new URL(url).pathname.replace(/\//g, '-').replace(/^-+|-+$/g, '') || 'root' +``` + +Depending on how you format your input array, this cleanup step may be unnecessary. + +```ts +const monitorId = `checkly-${urlPath}-ping` +``` + +The monitor’s logical ID should stay as stable as possible in later updates. When you deploy this monitor to Checkly, a matching ID will be updated with the history of the monitor preserved. A new Logical ID will mean a new monitor is created, and any IDs that were previously deployed from this project that are now missing will be deleted! If you want to double-check your settings, be sure to run the preview command `npx checkly deploy -p` before deploying (for more detail on this, check out the [guide to creating URL Monitors](https://www.checklyhq.com/guides/url-monitoring/)). By contrast, feel free to update the syntax on the `name` value as much as you would like, this just updates the displayed name. + +```ts +UrlAssertionBuilder.statusCode().equals(200), +``` + +A URL Monitor is the most basic type of monitor that Checkly offers, so the `UrlAssertionBuilder` class only allows you to check the status code. For more advanced assertions on the response, try an [API check](https://www.checklyhq.com/docs/api-checks/#cli-example). + +## Parse a Sitemap and Monitor Every URL + +As just one extension of this concept, rather than manually downloading and parsing a list of URLs into an array, why don’t we parse our site’s sitemap into a list of URLs to monitor? This extension of the check above grabs a sitemap from a given URL and parses it to create our URL array. + +```ts +// sitemapUrlMonitors.check.js +import * as https from 'https'; +import { Frequency, UrlMonitor, UrlAssertionBuilder } from 'checkly/constructs' +const sitemapUrl = 'https://openai.com/sitemap.xml/webinar/'; + +function downloadSitemap(url: string): Promise { + return new Promise((resolve, reject) => { + https.get(url, (response) => { + let data = ''; + + response.on('data', (chunk) => { + data += chunk; + }); + + response.on('end', () => { + resolve(data); + }); + + response.on('error', (error) => { + reject(error); + }); + }).on('error', (error) => { + reject(error); + }); + }); +} + +function parseSitemap(xmlContent: string): string[] { + const urls: string[] = []; + // Simple regex to extract URLs from tags + // this should work for most sitemaps but isn't universal. + const locRegex = /(.*?)<\/loc>/g; + let match; + + while ((match = locRegex.exec(xmlContent)) !== null) { + urls.push(match[1]); + } + + return urls; +} + +console.log(`Downloading sitemap from: ${sitemapUrl}`); + +try { + const xmlContent = await downloadSitemap(sitemapUrl); + console.log('Sitemap downloaded successfully'); + + const sitemapUrls = parseSitemap(xmlContent); + console.log(`Found ${sitemapUrls.length} URLs in sitemap`); + console.log('\nSitemap URLs:'); + console.log(sitemapUrls); + + //create paths and friendly names for each monitor + sitemapUrls.forEach((url, index) => { + const urlPath = new URL(url).pathname.replace(/\//g, '-').replace(/^-+|-+$/g, '') || 'root' + const monitorId = `checkly-${urlPath}-ping` + const monitorName = `Checkly ${urlPath.replace(/-/g, ' ')} Monitor` + + //create each monitor with a five minute interval + new UrlMonitor(monitorId, { + frequency: Frequency.EVERY_5M, + name: monitorName, + activated: true, + request: { + url: url, + skipSSL: false, + followRedirects: true, + assertions: [ + UrlAssertionBuilder.statusCode().equals(200), + ] + } + }) + }) +} catch (error) { + console.error('Error:', error); + process.exit(1); +} +``` + +Let's test these URL monitors and preview their deployment with: + +```bash +npx checkly test && npx checkly deploy -p +``` + +If you're using the sitemap URL above (for a list of OpenAI webinar pages), you'll get a short list of monitors that have been tested: + +![A terminal](/guides/images/monitor-many-urls-02.png) + +Followed by the deployment preview: + +![A terminal](/guides/images/monitor-many-urls-03.png) + +If these look correct, you’re ready to run `npx checkly deploy` and create your new monitors! + +## Next Steps: Grouping, and More Advanced Checks + +With all of our monitors managed with a single file, we can update their configuration just by changing the values in the `new UrlMonitor` block above. However, as we have more detailed and nuanced monitoring, it would be nice to have a single place to manage configuration for timing, alerting, and notification channels for a group of checks. All of that is possible with Checkly Groups. + +Next, we’d like to apply these tools to more advanced check types like API checks and Browser checks written with Playwright. Check out our documentation on [dynamic monitor creation](https://www.checklyhq.com/docs/cli/dynamic-check-creation/) to see examples of these more complex checks. + +# Conclusion + +Can you really monitor 500 pages in two minutes? Absolutely! + +With Checkly’s **Monitoring as Code** approach, scaling your monitoring to hundreds or even thousands of pages is effortless. By leveraging Checkly constructs, sitemap parsing, and dynamic monitor creation, you can ensure comprehensive coverage of your website, API routes, and third-party services—all from a single configuration file. + +**Key Takeaways:** + +- Bulk URL Monitoring: Easily create multiple URL monitors from an array or sitemap. +- Flexible Configuration: Adjust frequency, assertions, and naming dynamically. +- Preview Before Deploy: Use `npx checkly deploy -p` to verify changes before applying them. +- Extend to Advanced Checks: Apply the same principles to [API checks](https://www.checklyhq.com/docs/api-checks/) and [browser checks](https://www.checklyhq.com/docs/browser-checks/). + +For more details on structuring and managing your monitors, check out our guides on: + +- [Creating URL Monitors](https://www.checklyhq.com/docs/url-monitors/) +- [Dynamic Monitor Creation](https://www.checklyhq.com/docs/cli/dynamic-check-creation/) +- [Organizing Checks with Groups](https://www.checklyhq.com/docs/groups/) + +Ready to supercharge your monitoring? Start deploying with Checkly and keep your applications reliable at scale! 🚀 \ No newline at end of file