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 thecover_img
with the screenshot URL.
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
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 thepreview_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:
- User Input: The user enters a URL in the
InputText
field. - API Request: Clicking the "Snapshot" button triggers
getSnapshot
, sending the URL to the backend. - Backend Processing: The backend generates a screenshot using Puppeteer and returns the image path.
- 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!
Comments ()