You might need to display popup boxes at various scenarios while creating interactive user interfaces. By default, JavaScript does allow you to display popups.

An alert box is the simplest one.

alert("Hello World!");

Then you have the confirm box that presents the user with an option to click either the OK or Cancel button, in order to confirm an action like deleting an item.

const confirm = confirm("Are you sure you wanna continue?");

Then you also have the Prompt box, which allows the user to input a value and submit it, or cancel.

const myName = prompt("Enter your name:");

But overall, you can see that all these default browser boxes are plain and utilitarian. It may not match with the overall design of your web app.

I’ve looked for alternatives, but by far SweetAlert is what I liked the most, because of it’s verstility and customization options. So, in this video we’ll have a quick look at how you can integrate SweetAlert into your projects along with some example use cases.

By playing this video, you agree to YouTube's Terms
Watch on YouTube →

Now let’s see how you can get started with SweetAlert.

This official website mentions a few different ways. The easiest way is to include the CDN link in the HTML head. However, the recommended way is to install the package from NPM and then bundle it using Webpack, or some other tool like that. Or if you are using React, then there are options for that as well. In this video, I will show you the recommended way itself, that is, installing it from NPM.

Installing SweetAlert

Start by initiating an npm repository in the project folder. Then grab the install command and run it.

npm install sweetalert --save

The SweetAlert package will be added to the node_modules folder.

Now you can start using SweetAlert within ES6 modules. Go to the main JavaScript file, where we already have function that displays a basic alert box.

Import SweetAlert at the top.

import swal from "sweetalert";

Let’s just replace the basic alert box with a SweetAlert box.

swal("Hello World!");

However, import is an ES6 module syntax, which won’t work straight away in the browser. I’ve tried setting the type="module" attribute, but that also turned out to be problematic.

So, the recommended way is to bundle the module code using Webpack. For that we need to install webpack and webpack-cli, just like we installed sweetalert from npm.

npm install webpack webpack-cli --save-dev

Note that this time I added the --save-dev option because Webpack is required only during development. What Webpack does is, it watches for changes in our JavaScript file, then compiles and bundles the code into another file that we can include within the HTML script tag.

The only thing you need is, keep running the following command in a terminal window:

npx webpack

By the way, the npx command can execute scripts without installing them. So the previous npm install command is not a necessity. But still, installing it is a good idea since it adds the exact webpack version to the package.json file. npx fetches the latest version from the remote npm registry only if the version is not mentioned in the package.json file. If someone clones your project later, they will also get to use the same version you used, avoiding any potential compatibility issues.

You may also create an alias command withing the script section of the package.json file:

"npm run webpack": "npx webpack"

One more thing, webpack by default saves the compiled file into the /dist folder. Also, it won’t watch for file changes by default.

So let’s also create a configuration file: webpack.config.js, that contains the following code:

const path = require('path');

module.exports = {
    entry: {
        './js/basic-alert.bundle.js': './js/basic-alert.js',
        './js/main.bundle.js': './js/main.js'
    },
    output: {
        filename: '[name]',
        path: path.resolve(__dirname),
    },
    mode: 'development',
    watch: true,
    watchOptions: {
        aggregateTimeout: 1000,
        poll: 1000
    },
};

This sets the output path to the same directory where the source file also exists. It also sets the watch option to true, so webpack keeps running looking for file changes, and compiling every 1000ms.

Finally, don’t forget to change the src attribute of the script tag in our HTML file.

<script src="js/basic-alert.bundle.js"></script>

Basic Usage With a Simple Alert

Now let’s try replacing the basic alert box with an equivalent SweetAlert box:

swal("Hello World!");

Reload the page, and you can already see how better it is.

But that’s not all. SweetAlert offers a variety of features. Here are a few reasons why I liked it:

  1. Ability to show icons
  2. Ability to set multiple buttons and their values
  3. Returns JavaScript Promises, allows chaining multiple alerts
  4. Supports for input field
  5. Ability to set the return value for the confirm button

Let’s take a look at each of them.

Success, Error, Info & Warning Alerts

In the above Hello World example, we just passed a simple string to the swal function. On the other hand, changing the argument to an object gives you a lot more options.

Not only the alert message, but you can also set an icon, title, and a message text, along with the buttons (one or more).

Speaking of icons, SweetAlert supports four types:

  1. success
  2. error
  3. info
  4. warning

Here is how to make a simple success alert, by setting the value of the icon property to success:

swal({
    "title": "Saved",
    "text": "Your priorities have been saved successfully",
    "icon": "success"
})

Let’s take something in the real world. Suppose a user is submitting a form. Once it is submitted successfully, you can show a success alert:

const result = await fetch('backend.php', {
    method: 'POST',
    body: data,
});

const json = await result.json();

switch (json.status) {
    case 'success':
        swal({
            "title": "Saved",
            "text": json.message,
            "icon": "success"
        });
        break;
    case 'error':
        swal({
            "title": "Check Again!",
            "text": json.message,
            "icon": "error"
        });
        break;
}

In the above example, it sends the form data to the backend service using the Fetch API. And we show a success or error alert based on the data returned by the backend API.

Playing with Multiple Buttons

You can also control the buttons, including their styles and how they behave by setting the buttons property. By default, it displays only the OK button with its value set to true.

Setting buttons: true would display two buttons, a Cancel button with its default value set to null, along with the OK button (true).

You can also display more than two buttons by setting the property to an object.

Imagine you run a subscription service. A premium user is about to delete their account. Then instead of just deleting straight away, you can encourage them to stay longer by continuing with a free account. So the alert can show three buttons:

  • Pause Subscription and continue with a free account
  • Delete account permanently
  • Cancel the action
import swal from "sweetalert";

const deleteBtnClick = async (event) => {

    event.preventDefault();

    const confirmation = await swal({
        title: 'Think for a minute!',
        text: 'Your action cannot be reversed! May be you can pause subscription and continue with the free plan',
        icon: 'warning',
        buttons: {
            delete: {
                text: "Delete Account",
                value: 'delete',
                className: "btn btn-danger btn-sm",
            },
            cancel: {
                text: "Cancel",
                value: null,
                className: 'btn btn-secondary btn-sm',
                visible: true,
            },
            pause: {
                text: "Pause Subscription",
                value: 'pause',
                className: "btn btn-success btn-sm",
            },
        }
    });

    switch (confirmation) {
        case 'delete':
            console.log('account deleted permanently');
            break;
        case 'pause':
            console.log('pause account');
            break;
        default:
            console.log('Glad you are back!');
    }

}

const deleteBtn = document.getElementById('delete-account');

if (deleteBtn) {
    deleteBtn.addEventListener('click', deleteBtnClick);
}

Notice how I used the className property to make the buttons look like Bootstrap buttons. Maybe you can add a pinch of custom CSS to make it completely customized.

But more importantly, notice how I could set the button text, and the value for each of the three buttons, then captured the selected value using async await. And that brings me to the next point – the swal() function returns a Promise. That’s why I could add the await keyword in front of it, so that the page waits until the user clicks a button. And the when a button is clicked, the Promise gets resolved to the button’s value.

What does that mean?

You can chain a second alert box based on the value selected in the first.

Chaining Alerts with Promises

Suppose you run some kind of show booking site, movies, concert, something like that. And you want to allow users to check ticket availability by entering the show time.

In the first popup box, you can ask for the show time – for instance, morning or evening. Then use that value to check the availability and display the result in the second popup.

import swal from "sweetalert";

const startBooking = document.getElementById('start-booking');

const tickets = {
    morning: 1,
    evening: 0,
}

const startBookingOnClick = async (event) => {
    event.preventDefault();

    const showTime = await swal({
        title: "Choose a Show Time",
        text: "Morning show starts @ 9am, ends @ 10am, Evening show starts @ 4pm, ends @ 5pm",
        buttons: {
            morning: {
                text: "Morning",
                value: "morning"
            },
            evening: {
                text: "Evening",
                value: "evening",
            }
        }
    });

    if (showTime) {

        if (tickets[showTime] > 0) {
            swal({
                title: "Voila!",
                text: "Tickets Available for " + showTime + " show",
                icon: "success",
            });
        }
        else {
            swal({
                title: "Sorry!",
                text: "Tickets currently not available for " + showTime + " show, check again tomorrow",
                icon: "info",
            });
        }

    }
}

if (startBooking) {
    startBooking.addEventListener('click', startBookingOnClick);
}

Now, rather than just checking the availability, you can chain more alerts to allow purchasing tickets as well.

But for that, the user needs a way to enter the no. of tickets to buy, right?

SweetAlert allows that as well, with the content property. It looks like this:

noOfTickets = await swal({
    title: "Select Tickets",
    text: "Please select the no. of tickets you want",
    content: {
        element: "input",
        attributes: {
            type: "number",
            min: 1,
            max: tickets[showTime],
            value: 1
        }
    },
    button: "Get Tickets"
});

Notice that I’ve set element to input, which creates an HTML input field within the alert box. Also, set the required attributes like type, minimum value, and maximum value. See how we could use the max value based on the previous response, i.e., tickets[showTime].

Finally when the user clicks the Get Tickets button, swal resolves to the number entered in the input field, which we can use to display the final alert box.

So, the whole code looks like this:

import swal from "sweetalert";

const startBooking = document.getElementById('start-booking');

const tickets = {
    morning: 3,
    evening: 0,
}

const startBookingOnClick = async (event) => {
    event.preventDefault();

    let showTime = '';
    let buyTickets = false;
    let noOfTickets = 0;

    showTime = await swal({
        title: "Choose a Show Time",
        text: "Morning show starts @ 9am, ends @ 10am, Evening show starts @ 4pm, ends @ 5pm",
        buttons: {
            morning: {
                text: "Morning",
                value: "morning"
            },
            evening: {
                text: "Evening",
                value: "evening",
            }
        }
    });

    if (showTime) {

        if (tickets[showTime] > 0) {
            buyTickets = await swal({
                title: "Voila!",
                text: "Tickets Available for " + showTime + " show",
                icon: "success",
                buttons: {
                    cancel: {
                        text: 'Cancel',
                        visible: true,
                    },
                    buy: {
                        text: 'Buy Tickets',
                    }
                }
            });
        }
        else {
            swal({
                title: "Sorry!",
                text: "Tickets currently not available for " + showTime + " show, check again tomorrow",
                icon: "info",
            });
        }

        if (buyTickets) {
            noOfTickets = await swal({
                title: "Select Tickets",
                text: "Please select the no. of tickets you want",
                content: {
                    element: "input",
                    attributes: {
                        type: "number",
                        min: 1,
                        max: tickets[showTime],
                        value: 1,
                    }
                },
                button: "Get Tickets"
            });
        }

        if (noOfTickets) {
            swal({
                title: "Thank You!",
                text: noOfTickets + " tickets booked for " + showTime + " show",
                icon: "success"
            });
        }
        else {
            swal({
                title: "Cancelled!",
                text: "Ticket Booking Cancelled",
                icon: "error"
            });
        }

    }
}

if (startBooking) {
    startBooking.addEventListener('click', startBookingOnClick);
}

Custom HTML & setActionValue

But in some cases, you might need to create more complex forms fields. For instance in the above example, a show may have several timings, rather than just ‘morning’ and ‘evening’. What if you want to show 4 options? ‘morning’, ‘noon’, ‘evening’, and ‘night’? Of course, you can create 4 buttons, but that is not a great idea.

Instead, a select field with 4 options would be better. But by default, there is no option for that. Fortunately, SweetAlert allows custom HTML within the content property.

Here is how you can do that:

const selectShowTimeFormHTML = `<select id="show-time-selector" class="form-select" aria-label="Default select example">
<option value="morning">Morning</option>
<option value="noon">Noon</option>
<option value="evening">Evening</option>
<option value="night">Night</option>
</select>`;

const parser = new DOMParser();
const doc = parser.parseFromString(selectShowTimeFormHTML, 'text/html');
const selectField = doc.getElementById('show-time-selector');

Now, we have the HTML element within the constant selectField. Set it as the value of the content property in our first swal() call:

showTime = await swal({
    title: "Choose a Show Time",
    text: "Morning show starts @ 9am, noon show starts @ 12am, evening show starts @ 4pm, night show starts @ 8pm",
    content: selectField,
    button: {
        text: "Check Availability",
        value: selectField.value ? selectField.value : "morning",
    }
});

That gives us an alert box with a select field and a button. But still there is a problem. How is SweetAlert supposed to know the select field value when someone selects an option?

Again, SweetAlert gives a function called setActionValue, which allows setting the value for the OK button whenever you want. So we can combine that with the onchange event to achieve the result we want.

const selectFieldOnChange = async (event) => {
    swal.setActionValue(event.target.value);
}

selectField.addEventListener('change', selectFieldOnChange);

Conclusion

In the above sections, we’ve slowly advanced from a simple alert box to more complex examples where we customized the buttons, gather user inputs, and even changed the HTML. With that, I hope now you have a good understanding on how to use SweetAlert.