Screenshot Webpage with html2canvas and Save the Image to Laravel Backend

https://postsrc.com/storage/E66UDCZqY5q68i4ErmhUYmgg18qj3r7Pkk2hO495.jpg

In this short post, you will learn how to implement/take a screenshot of a webpage using

html2canvas library

. The screenshot will then be sent back to the Laravel as the backend using Axios HTTP client. The implementation steps are very simple so let’s get started.

Html2canvas Homepage

Step 1: Install html2canvas

To install the

html2canvas

library you can either use npm or yarn.

npm install --save html2canvas

yarn add html2canvas

For an alternative, if you prefer the CDN version then just reference the script at the end of your body tag.

<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>

Step 2: Import html2canvas to your project

To import the library to your project you make use of JavaScript “import” module. Do note that if you are not using a build library, you can use the “require” keyword and reference it to the windows object.

import html2canvas from 'html2canvas';
window.html2canvas = html2canvas;

The “require” keywords are as follows.

window.html2canvas = require('html2canvas');

Step 3: Take Screenshot with html2canvas

To take a screenshot with this library you can call the function directly from within your page script section. The code below will take a screenshot of the “document.body” and then append it to the body to show a preview of the page being screenshotted.

<script>
    html2canvas(document.body).then(function(canvas) {
        document.body.appendChild(canvas);
    });
</script>

If you want to make use of html2canvas to take a screenshot of a “div” tag or an “iframe” tag, you can “query select” the tag and pass it into the html2canvas function.

let specialDiv = document.getElementById('special-div'); // getting special div
let someIframe = document.querySelector('.some-iframe'); // getting some iframe

And when you have the reference to the element, you can just pass in and call the “then” method.

html2canvas(specialDiv).then(function(canvas) {
    document.body.appendChild(canvas);
});

Step 4: Save the screenshot as JPEG or PNG

To save the screenshot as a “jpeg” or “png” format, you can pass the canvas object to any of your backends by sending an ajax like below. In this case we’ll be using the Axios HTTP library.
If you have not install axios HTTP library, then do run the command below.

npm install axios
yarn install axios

Do note that the image will be passed as a “FormData” object and the Axios have a “multiplart/form-data” set as the headers. For this example, we’ll just console log the message that will be retrieved from the backend. In the normal scenario, you can provide a notification or some sort of alert to notify the user.

let specialDiv = document.getElementById('special-div'); // getting special div

html2canvas(specialDiv)
    .then(canvas => {
        let data = new FormData();
        data.set('image', canvas.toDataURL("image/jpeg", 1));
    
        axios.post('/save-screenshot', data, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        })
        .then((data) => {
            console.log('message: ', data.data.message);
        })
        .catch(error => {
            console.log('error: ', error);
        })
    });

Step 5: Setup the backend Logic

For this example, we’ll be using the Laravel framework as the backend. The backend logic should load the image as a stream and then save the image to the disk using the “Storage” facade. Do note that the code below only shows how the image is saved but the filename itself is returned to the client/front-end (possibly to show the user that the image is already inside the storage).

Route::post('/save-screenshot', function (Request $request) {
    /* generate the image stream */
    $imageStream = Image::make($request->image) /* base64_decode */
        ->stream('webp', 100);

    /* create the image path */
    $imagePath = '/img/image-name.png';

    /* store image to disk */
    Storage::disk('public')
        ->put($imagePath, $imageStream, 'public');

    return response()->json([
        'message' => 'The image has been successfully saved',
        'image_path' => $imagePath
    ]);
});

Optional: Store Filename to DB

To store the file name into the database you can directly call the “Laravel Model” or the “DB” facade itself. For example, if this screenshot is for an article, you can write your code like below.

Article::first()->update(['poster' => $imagePath]);

Laravel News Links