Part 2 - Building the Frontend for Screenshot Generation with Nuxt 3

Part 2 - Building the Frontend for Screenshot Generation with Nuxt 3

Welcome to part two of our tutorial on integrating Puppeteer into your Nuxt 3 app. In part one, we set up the backend to capture website screenshots by passing a URL to Puppeteer. Now, it’s time to create the frontend—a sleek and interactive interface where users can input a URL, trigger the screenshot process, and view the result in real-time.

In this tutorial, we’ll break the setup into logical parts, guiding you through each step to build a polished and functional frontend. Let’s dive in!


Part 1: Setting the Stage

We begin by creating the foundation of our interface. The main goal is to provide a user-friendly experience where users can input a URL and see the generated screenshot.

Defining the Essentials

Here’s the basic setup in index.vue:

<script setup>
const { $axios, $showAutoSave } = useNuxtApp(); // Access global Nuxt functions
const ajax_url = `http://localhost:3000/screenshot`; // Backend endpoint

const emit = defineEmits(['onCoverUpdated']); // Emit event to parent

// Reactive states
const loading_snapshot = ref(false); // Controls snapshot button loading state
const preview_url = ref(''); // URL entered by the user
const cover_img = ref(''); // Stores the generated screenshot URL

// Trigger screenshot generation
const getSnapshot = async () => {
    loading_snapshot.value = true;

    try {
        const response = await $axios({
            url: ajax_url,
            method: 'GET',
            params: { url: preview_url.value },
        });

        if (response.http_path) {
            loading_snapshot.value = false;
            cover_img.value = response.http_path;
            emit('onCoverUpdated', response.http_path);
        }
    } catch (error) {
        loading_snapshot.value = false;
        console.error('Error capturing the snapshot:', error);
    }
};
</script>
  • Global Functions: We use $axios for making HTTP requests to the backend endpoint.
  • Reactive Variables: These manage the loading state, input value, and generated screenshot URL.
  • API Call: The getSnapshot function sends the URL to the backend and updates the cover_img with the screenshot URL.

2220+ FREE RESOURCES FOR DEVELOPERS!! ❤️😍🥳 (updated daily)
1400+ Free HTML Templates
347+ Free News Articles
66+ Free AI Prompts
311+ Free Code Libraries
51+ Free Code Snippets & Boilerplates for Node, Nuxt, Vue, and more!
25+ Free Open Source Icon Libraries
Visit dailysandbox.pro for free access to a treasure trove of resources!

Part 2: Designing the User Interface

Now that the logic is in place, let’s create a visually appealing interface. Users need a text field to input the URL and a button to trigger the screenshot.

Building the Template

<template>
    <div class="container">
        <!-- Display Cover Image -->
        <div class="row mb-3">
            <label for="coverImg" class="form-label">Cover Image</label>
            <div class="d-flex flex-gap-20">
                <div class="col-12">
                    <img :src="cover_img" alt="Cover Image" class="cover-img-preview rounded" />
                </div>
            </div>
        </div>

        <!-- Input Field for URL -->
        <div class="row mb-3">
            <label for="preview_url" class="form-label">Preview URL</label>
            <div class="d-flex flex-gap-20 align-items-center">
                <div class="col-9">
                    <InputText id="preview_url" v-model="preview_url" class="w-100 mr-2" />
                </div>
                <div class="col-3 d-flex justify-content-end">
                    <Button
                        label="Snapshot"
                        class="snapshot-control"
                        icon="ti ti-camera"
                        :loading="loading_snapshot"
                        @click="getSnapshot"
                    />
                </div>
            </div>
        </div>
    </div>
</template>
  • Cover Image: Displays the generated screenshot dynamically. The cover_img variable updates as soon as the backend responds.
  • Input Field: The v-model binds the user’s URL input to the preview_url variable.
  • Snapshot Button: The button is styled and linked to getSnapshot. Its :loading state ensures visual feedback when the process is running.

Part 3: Styling for Elegance

A good interface is both functional and beautiful. Here’s the accompanying CSS to style the page:

<style lang="less" scoped>
.cover-img-preview {
    max-width: 100%;
    border: 1px solid #ddd;
    padding: 10px;
    background-color: #f9f9f9;
    border-radius: 8px;
}
.snapshot-control {
    width: 100%;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 5px;
    padding: 10px;
    font-weight: bold;
    cursor: pointer;
    transition: background-color 0.3s;

    &:hover {
        background-color: #0056b3;
    }

    &:disabled {
        background-color: #cccccc;
        cursor: not-allowed;
    }
}
</style>
  • Cover Image Preview: The preview is styled with a border, background color, and rounded corners to make it visually distinct.
  • Snapshot Button: Styled for responsiveness and clarity, with hover effects for a modern touch.

Part 4: Connecting the Backend and Frontend

The getSnapshot function calls the Puppeteer-powered backend to fetch the screenshot. Let’s revisit the flow:

  1. User Input: The user enters a URL in the InputText field.
  2. API Request: Clicking the "Snapshot" button triggers getSnapshot, sending the URL to the backend.
  3. Backend Processing: The backend generates a screenshot using Puppeteer and returns the image path.
  4. Frontend Update: The cover_img variable updates with the image URL, dynamically updating the <img> tag.

The Final Result

Your Nuxt 3 frontend is now seamlessly connected to the Puppeteer backend. Users can input a URL, trigger a screenshot, and see the results in real-time. The interface is intuitive, responsive, and visually appealing—an excellent showcase of Nuxt 3’s power and flexibility.

For more tips on web development, check out DailySandbox and sign up for our free newsletter to stay ahead of the curve!