ScreenshotNeo

BlogHow-to

How to Schedule Recurring Website Screenshots with Node.js on Windows in India

Use Playwright for website screenshots and Windows Task Scheduler to run them on an India-time schedule. Includes setup, runnable code, troubleshooting, and a no-browser alternative.

By the ScreenshotNeo team4 October 202610 min read

Direct answer: use Playwright in a Node.js script to open the website and save a screenshot, then use Windows Task Scheduler to run that script on a daily, weekly, or other recurring schedule. The run time follows the Windows machine’s configured time zone, so set it to India Standard Time (IST) and confirm the task’s next-run time on that machine.

This guide covers a local Windows setup. The Node.js process performs the capture; Task Scheduler controls when it runs. For a simpler scheduled capture that does not require your own browser installation, see ScreenshotNeo after the DIY setup.

1. Choose what the recurring screenshot should contain

Decide these details before scheduling so every run produces the intended result:

  • Capture scope: use a viewport screenshot for the visible browser area, or a full-page screenshot for the page’s scrollable content.
  • Output policy: overwrite one file to keep only the latest capture, or create timestamped files to keep a history.
  • Page readiness: choose when to capture. Waiting for network idle can help on mostly static sites, but some pages keep background requests open. A fixed delay or a specific selector can be a better readiness signal for a particular site.
  • Schedule: choose a daily, weekly, or monthly trigger, or a repeating interval where supported.

A browser screenshot records the page as rendered at that time. Live data, personalization, animations, rotating banners, and consent dialogs can make captures differ between runs.

2. Install Node.js and set up Playwright

  1. Install a supported Node.js release on the Windows computer that will run the task.
  2. Create a project folder, for example C:\website-capture, and open PowerShell in that folder.
  3. Initialize the project and install Playwright:
npm init -y
npm install playwright
npx playwright install chromium

Playwright needs its browser runtime in addition to the npm package. Install the browser using the command for the Playwright version installed in this project; see the official browser installation guide if the command or supported browser choices differ.

3. Create a reliable screenshot script

Save this as C:\website-capture\capture.js. It creates the output directory, uses a timestamped filename, logs success or failure, and always closes the browser. Change the target URL and viewport to suit the site.

const fs = require('node:fs/promises');
const path = require('node:path');
const { chromium } = require('playwright');

const targetUrl = 'https://example.com';
const outputDir = path.join(__dirname, 'screenshots');
const viewport = { width: 1365, height: 900 };

function fileTimestamp(date = new Date()) {
  // Use a filename-safe local timestamp. The machine's configured time zone
  // determines this local time; set Windows to India Standard Time for IST.
  const parts = new Intl.DateTimeFormat('en-CA', {
    timeZone: 'Asia/Kolkata',
    year: 'numeric', month: '2-digit', day: '2-digit',
    hour: '2-digit', minute: '2-digit', second: '2-digit',
    hourCycle: 'h23'
  }).formatToParts(date);
  const get = (type) => parts.find((part) => part.type === type).value;
  return `${get('year')}-${get('month')}-${get('day')}_${get('hour')}-${get('minute')}-${get('second')}`;
}

(async () => {
  await fs.mkdir(outputDir, { recursive: true });
  const outputPath = path.join(outputDir, `example-${fileTimestamp()}.png`);
  const browser = await chromium.launch({ headless: true });

  try {
    const page = await browser.newPage({ viewport });
    await page.goto(targetUrl, { waitUntil: 'networkidle', timeout: 60_000 });
    await page.screenshot({ path: outputPath, fullPage: true });
    console.log(`Screenshot saved: ${outputPath}`);
  } catch (error) {
    console.error(`Capture failed for ${targetUrl}:`, error);
    process.exitCode = 1;
  } finally {
    await browser.close();
  }
})();

The timestamp is explicitly formatted in the Asia/Kolkata time zone so filenames remain in India local time even if the machine is configured differently. Task Scheduler itself uses the machine’s configured time zone for its trigger. If you prefer the Windows setting to be the single source of truth for both, remove the timeZone option from the formatter and configure Windows as described below.

Run it interactively before creating a task:

node C:\website-capture\capture.js

Confirm that a PNG appears in C:\website-capture\screenshots and inspect it. If the site is not finished loading at capture time, adjust the readiness condition in the next section.

4. Tune page readiness and screenshot options

Wait for a page state that suits the site

The example uses waitUntil: 'networkidle'. That works for many ordinary pages, but sites with persistent polling or analytics requests may never become idle before the timeout. Other options include waiting for the initial page load or waiting for a page-specific selector after navigation:

await page.goto(targetUrl, { waitUntil: 'load', timeout: 60_000 });
await page.locator('main article').waitFor({ state: 'visible', timeout: 15_000 });
await page.screenshot({ path: outputPath, fullPage: true });

For a known short rendering delay, use a bounded wait rather than an indefinite pause:

await page.goto(targetUrl, { waitUntil: 'domcontentloaded', timeout: 60_000 });
await page.waitForTimeout(2_000);
await page.screenshot({ path: outputPath, fullPage: true });

Use the smallest wait that reliably captures the intended content. A longer wait increases run time and may not make dynamic content deterministic.

Viewport or full page

Set fullPage: false (or omit it) to capture the viewport. Set fullPage: true to capture the full scrollable page. Full-page images can be very tall and use more memory; for especially long pages, viewport captures or a PDF workflow may be more manageable.

Format, scale, and output

The Page screenshot API supports a file path, image type, and scale, among other options. The file extension in this example is PNG. You can choose JPEG with a quality setting or WebP where supported by your installed Playwright version. A buffer can be returned instead of writing directly to disk when you need to upload or process the image in the script.

// Viewport-only JPEG example
await page.screenshot({ path: outputPath, type: 'jpeg', quality: 80 });

// Buffer example
const imageBuffer = await page.screenshot({ type: 'png', fullPage: false });
await fs.writeFile(outputPath, imageBuffer);

For the full option list and version-specific behavior, use the official Page API reference. Keep output extensions consistent with the selected image format.

Overwrite instead of archiving

To keep only the latest screenshot, replace the timestamped path with a fixed path such as:

const outputPath = path.join(outputDir, 'latest.png');

For archives, calculate a timestamp as above and periodically delete older files according to your retention needs. A frequent schedule with timestamped files can consume disk space quickly.

5. Configure Windows and schedule the recurring run

  1. Set the Windows time zone to India Standard Time (UTC+05:30). Confirm the current date and time shown by Windows.
  2. Open Task Scheduler and choose Create Task (or the basic task wizard).
  3. On Triggers, add a time-based trigger and choose its start date, time, and recurrence: daily, weekly, or monthly. Where the task UI supports repetition, set the repeat interval and duration.
  4. On Actions, add Start a program. Set Program/script to the full path of node.exe (find it with where node in a terminal using the same Windows account). Set Add arguments to C:\website-capture\capture.js. Set Start in to C:\website-capture.
  5. Choose the account and run conditions deliberately. The task identity needs permission to read the project and write to the screenshots directory. If the task must run while no one is signed in, configure an account and credentials that permit that mode.
  6. Save the task, run it manually from Task Scheduler once, and confirm the output file and task history.
  7. Check the displayed Next Run Time. Confirm it matches the intended India local time on the target computer.

Windows Task Scheduler supports time-based triggers and recurring schedules. See Microsoft’s trigger overview and schtasks /create reference for schedule types, start times, and repeat intervals. The Task Scheduler service runs selected programs when their configured criteria occur; see Microsoft’s Task Scheduler overview.

Optional: create a daily task from the command line

For a daily run at 9:00 PM local machine time, an administrator or task owner can create a task with schtasks. Replace the paths and task name as needed. Run the command in a terminal with permissions appropriate for the chosen task account:

schtasks /create /tn "Website screenshot" /sc daily /st 21:00 /tr "\"C:\Program Files\nodejs\node.exe\" \"C:\website-capture\capture.js\"" /f

Quoting rules can be easy to get wrong when an executable or script path contains spaces. If the action fails, configure it through the Task Scheduler GUI or verify the exact command line and quoting. The command above uses the machine’s local schedule time; verify the resulting next-run display. Microsoft documents additional schedule and identity parameters in the command reference.

6. Keep the capture repeatable and the task reliable

  • Use absolute paths: scheduled tasks may start with a different working directory than an interactive terminal. Set Start in and use a known project/output path.
  • Prepare the environment: install Playwright and its browser under the account that runs the task, or ensure that account can access the installed browser files.
  • Account for sleep and shutdown: a powered-off computer cannot run a local capture. Review task conditions for wake behavior if the machine supports it, and ensure it is available at the scheduled time.
  • Check task history and logs: keep the script’s success/error messages and inspect Task Scheduler’s last-run result when a capture is missing.
  • Prevent overlapping runs: if a page sometimes takes longer than the interval, configure the task to avoid starting another instance while the prior one is still running.
  • Manage retention: estimate archive growth from screenshot size and frequency; overwrite files or prune old captures if disk use matters.
  • Protect sensitive pages: avoid embedding passwords or long-lived credentials in source files. Do not capture authenticated or private pages unless the output location and access controls are appropriate.
  • Expect visual variation: use a stable viewport and page state, but account for personalized content, animation, changing data, and time-dependent banners.

Or skip the browser setup

ScreenshotNeo can capture a website with one API request, without installing Playwright or a browser on the Windows machine. The API supports PNG, JPEG, WebP, or PDF; use Windows Task Scheduler to invoke your preferred script or command on a recurring IST schedule. See the ScreenshotNeo API documentation for request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

With ScreenshotNeo, cookie banners are accepted and removed before the capture, along with known newsletter popups and chat widgets. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed; response headers identify the page verdict and billing status. Its MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

Troubleshooting

Symptom Likely cause Fix
Task runs but no screenshot appears Wrong script path, working directory, output permissions, or a different task account. Use absolute paths, set Start in, grant the task account write access, then run the task manually and inspect its history.
Executable doesn't exist or browser launch fails Playwright’s Chromium runtime is missing or inaccessible to the scheduled account. Run the Playwright browser install command for the project’s version and ensure it runs under, or is accessible to, the task identity.
Navigation times out The site is slow, unreachable from the machine, or never reaches network idle because of ongoing requests. Check the URL and connectivity; raise the timeout if justified, or use domcontentloaded/load followed by a selector wait.
Screenshot is blank or incomplete The capture occurs before client-rendered content is ready, or the page needs scrolling to load lazy content. Wait for the content selector, use a bounded delay if appropriate, or scroll the page before capture to trigger lazy loading.
Task runs at the wrong hour Windows is using a different time zone, or the task’s next run was interpreted in another local context. Set the computer to India Standard Time, save the trigger, and verify the displayed next-run time on that machine.
Works interactively but fails unattended The task has a different account, environment, permissions, or browser installation context. Use the intended task identity, install dependencies for that identity, set the working directory, and check task history.
Old screenshots disappear The script intentionally overwrites a fixed filename. Use timestamped names for an archive, or retain the fixed name for latest-only output.
Storage grows unexpectedly Timestamped captures accumulate faster than expected. Reduce capture frequency, choose a compact supported format and quality, or add a retention cleanup step.

Performance, reliability, and cost

A local Playwright workflow has no per-capture API fee, but it uses the Windows computer’s CPU, memory, network connection, and disk space. Full-page screenshots and high-resolution output can take more memory and produce larger files than viewport captures. Schedule captures at a frequency the machine and target site can handle, and avoid overlapping runs.

Reliability depends on the PC being available, the task account retaining access, the browser runtime remaining installed, and the target page loading successfully. Task Scheduler history and script logs help distinguish a missed trigger from a browser or network failure. If a capture must happen while the computer is off or unavailable, a local scheduled task cannot provide that guarantee.

ScreenshotNeo’s published plans are Free: 1,000 per month; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; and Business: $249 for 1,000,000. Yearly billing gives two months free. Every feature is on every plan. Only clean shots are billed; bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with verdict and billing information in response headers.

Frequently asked questions

Does Node.js control the recurrence?

No. Node.js performs one capture each time it is invoked. Windows Task Scheduler starts it according to the configured trigger.

Will the task run if the computer is shut down?

No. A local task needs the computer to be powered on and available. Sleep and wake behavior depends on the machine and task conditions.

Can I schedule more than one website?

Yes. Add multiple capture calls to a script, or create separate scripts and tasks. For many URLs, consider the runtime and site load involved in each run.

Will repeated screenshots be pixel-identical?

Not necessarily. Page data, personalization, animations, browser versions, and timing can change the rendered result. A fixed viewport and readiness condition improve consistency, but do not freeze the website itself.

Official references