Screenshot API for Vue.js

Capture screenshots, generate PDFs, and scrape web content from any Vue.js or Nuxt application. Server-side API calls keep your key secure; composable wrappers make the integration feel native.

Vue Composable (useScreenshot)

// composables/useScreenshot.ts
import { ref } from 'vue'

export function useScreenshot() {
  const loading = ref(false)
  const result = ref<string | null>(null)
  const error = ref<string | null>(null)

  async function capture(url: string, opts: Record<string, unknown> = {}) {
    loading.value = true
    error.value = null
    try {
      const res = await fetch('/api/screenshot', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ url, ...opts }),
      })
      const data = await res.json()
      result.value = data.url
    } catch (e) {
      error.value = String(e)
    } finally {
      loading.value = false
    }
  }

  return { loading, result, error, capture }
}

Using the Composable in a Component

<script setup lang="ts">
import { ref } from 'vue'
import { useScreenshot } from '@/composables/useScreenshot'

const { loading, result, error, capture } = useScreenshot()
const url = ref('')

async function handleCapture() {
  await capture(url.value, { fullPage: true, blockAds: true })
}
</script>

<template>
  <div>
    <input v-model="url" placeholder="https://example.com" />
    <button @click="handleCapture" :disabled="loading">
      {{ loading ? 'Capturing...' : 'Screenshot' }}
    </button>
    <p v-if="error" class="error">{{ error }}</p>
    <img v-if="result" :src="result" alt="Screenshot" />
  </div>
</template>

Nuxt Server Route (API Proxy)

// server/api/screenshot.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event)

  const res = await fetch('https://api.snapapi.pics/v1/screenshot', {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.SNAPAPI_KEY!,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  })

  return res.json()
})

Pinia Store Integration

// stores/screenshots.ts
import { defineStore } from 'pinia'

export const useScreenshotStore = defineStore('screenshots', {
  state: () => ({ items: [] as { url: string; screenshot: string }[] }),
  actions: {
    async capture(url: string) {
      const res = await $fetch('/api/screenshot', {
        method: 'POST', body: { url, fullPage: true }
      })
      this.items.push({ url, screenshot: res.url })
    },
  },
})

Pricing

Free: 200/mo. Starter $19/mo: 5K. Pro $79/mo: 50K. Business $299/mo: 500K. Get your free key — no card needed.

Vue.js Screenshot API — Use Cases and Patterns

Parameter Reference

ParameterTypeDefaultDescription
urlstringrequiredPage URL to capture
fullPagebooleanfalseCapture full scrollable height
widthinteger1280Viewport width px
devicestringDevice preset (iPhone 15 Pro, iPad Pro, etc.)
formatstringpngpng, jpeg, webp
blockAdsbooleanfalseBlock ads and trackers
waitUntilstringnetworkidleload, domcontentloaded, networkidle

Vue.js Use Cases

Link preview cards: when users paste a URL in your Vue app (a note-taking tool, a CMS, a project management app), capture it as a thumbnail and display the preview inline. The composable pattern above handles loading state naturally with Vue's reactivity system.

Automated OG images in Nuxt: for content-heavy Nuxt sites (blogs, docs, marketing pages), generate OG images server-side using a Nuxt server route that calls SnapAPI with a rendered template. Cache in a Nitro storage layer or your CDN.

Visual regression testing: capture components at different states (hover, active, disabled, loading) as screenshots and store them as baselines for visual regression tests. Run the pipeline in CI on every PR to catch style regressions before they reach users.

PDF export from Vue dashboards: let users export their current view as a PDF. Capture the live page URL (authenticated via a signed token) and return the PDF for download. No client-side PDF library needed.

Frequently Asked Questions

Does it work with Vue 2? Yes. The composable pattern requires Vue 2.7+ or the @vue/composition-api plugin. The underlying HTTP calls use standard fetch and work in any Vue version via a server-side proxy route.

Does it work with Vue Router? Yes. Capture any routed page by building its full URL. For protected pages, use server-side capture with a signed token validated by your auth middleware before rendering the HTML.

What about VitePress or VuePress? Both are Vue-based static site generators where OG image generation at build time makes sense. Call SnapAPI from your buildEnd hook after the site has been rendered to disk.

Can I use this with Nuxt Content? Yes. Generate OG images in a Nuxt server route and cache the result in your database or a Nitro KV store. The useScreenshot composable works with Nuxt's auto-imports system.

Start Free — 200 Captures/Month

No Chromium to install. Works on Vercel, Netlify, and any PaaS.

Get Free API Key

Vue vs Nuxt: Where to Put Your SnapAPI Calls

In a plain Vue SPA, all code runs in the browser. You cannot put your SnapAPI key in client-side JavaScript without exposing it. The solution is a backend proxy: your Vue app calls your own API endpoint (Express, Fastify, Django, Rails), which holds the key and forwards requests to SnapAPI. The composable above is written to call /api/screenshot on your own server, not SnapAPI directly.

In Nuxt, the server directory solves this cleanly. Nuxt server routes run on the server (Node.js) during SSR and as a serverless function on Vercel or Netlify. Your API key stays in process.env.SNAPAPI_KEY and never reaches the client bundle. This is the recommended pattern for Nuxt applications.

For Vue projects without a dedicated backend, a lightweight edge function (Cloudflare Worker, Vercel Edge Function) serves as the proxy. The function holds the API key in an environment variable and forwards screenshot requests to SnapAPI. This keeps your architecture serverless while protecting your credentials.

Multi-Device Screenshot Gallery Component

A common UI pattern for design tools and website builders: let users preview their site across devices. Trigger three concurrent captures (mobile, tablet, desktop), display them in a responsive grid with loading skeletons while captures complete. The Pinia store pattern handles this elegantly with reactive state across the three captures.

// Capture three devices in parallel
async function captureAllDevices(url) {
  const devices = ['iPhone 15 Pro', 'iPad Pro 12.9', 'Desktop Chrome']
  const results = await Promise.all(
    devices.map(device =>
      $fetch('/api/screenshot', {
        method: 'POST',
        body: { url, device }
      })
    )
  )
  return results.map((r, i) => ({ device: devices[i], url: r.url }))
}

Comparing SnapAPI to Self-Hosted Playwright in Vue

Self-hosting Playwright means running Chromium alongside your Node.js server. On Vercel or Netlify, this is impractical due to function size limits (50MB max, Chromium is 300MB+). On a custom VPS, you take on Chromium updates, crash monitoring, memory pressure from concurrent browser instances, and browser pool management. For most Vue/Nuxt applications, the operational cost exceeds the value of self-hosting.

SnapAPI keeps Chromium off your infrastructure. Your Nuxt server route makes an HTTP call, gets a hosted image URL, and returns it to the client. Your deployment stays a lean Node.js process with no system dependencies. This is especially valuable when deploying to serverless environments where binary dependencies are problematic.

Free plan: 200 captures/month with no credit card required. Starter at $19/month gives 5,000 captures for small production workloads. Pro at $79/month covers 50,000 captures, suitable for apps with regular user-triggered screenshots. All plans include screenshot, PDF, scrape, extract, video, and AI analysis under the same API key.

Getting Started

Register at snapapi.pics/register.html to get your free API key instantly. Email verification activates the key — the process takes under two minutes. The Free plan gives 200 captures per month with no credit card required, enough to validate any integration before deciding on a paid tier.

Full API documentation including live playground, all request parameters, response schemas, and code examples in JavaScript, Python, Go, PHP, Ruby, Swift, and Kotlin is at snapapi.pics/docs.html. The MCP server (npx snapapi-mcp) integrates directly with Claude Code, Cursor, VS Code, and Windsurf for AI-assisted development workflows.

All paid plans include all endpoints: screenshot, PDF, scrape, extract, video recording, and AI page analysis. There are no per-feature surcharges. Starter ($19/mo): 5,000 requests. Pro ($79/mo): 50,000 requests. Business ($299/mo): 500,000 requests. Annual billing saves approximately 20% on all plans.

Support is available via the chat widget on any page or by emailing support@snapapi.pics. Average response time is under four hours during business hours. Enterprise customers with custom quotas or SLAs can contact the team directly.

SnapAPI runs on dedicated infrastructure with Playwright and Chromium managed at the service level. Browser updates, stealth configuration maintenance, and proxy pool management are all handled transparently. Your integration stays stable across Chromium version updates without any code changes on your side.

Start Free Today

200 captures/month, no card required. Live in under 5 minutes.

Get Free API Key

SnapAPI is built and maintained by an independent team focused on reliability and developer experience. The API has been in production since 2024, serving customers across e-commerce, SaaS, media, and developer tooling verticals. Browser infrastructure runs on dedicated servers with automatic failover, daily health checks, and 24h watchdog processes ensuring consistent uptime. New SDK versions, documentation improvements, and feature releases are announced on the blog and via the changelog at snapapi.pics. Follow updates at @slwl_dev on X.