DEV Community

Paul Oms
Paul Oms

Posted on • Updated on

How to create a terminal simulation in the browser ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿง‘โ€๐Ÿ’ป

When demonstrating an API or similar service, your landing page should show how it works! You can easily use something like PrismJS to add syntax highlighting to your code snippets, which looks neat. But what about creating something a bit more compelling for the Hero unit of your landing page?

It needs to be simple and clear, and not necessarily syntactically correct, but it should look like a terminal, complete with a blinking cursor and simulated text entry. Something like this:

Simple terminal simulation in the browser

With the the help of TypedJS and TailwindCSS this is actually really easy.

Dependencies

Let's start by including TailwindCSS and Typed.js in our HTML <head> element:

<head>
    ...
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/typed.js@2.0.16/dist/typed.umd.js"></script>
</head>
Enter fullscreen mode Exit fullscreen mode

Note that you might want to use a pre-processor/build step or similar in production, and load them async etc.

Our Terminal window

We'll start by creating a <div> element with a class of terminal-window and a <pre> element with a class of terminal-output:

<div class="terminal-window">
    <pre id="terminal-output"></pre>
</div>
Enter fullscreen mode Exit fullscreen mode

Then let's style it a little with TailwindCSS, and add a close button, so it looks a bit like a terminal:

<div class="terminal-window mx-2 w-full xl:w-4/5 p-6 text-base sm:text-sm md:text-base rounded-md shadow-2xl bg-gray-800 max-h-80">
    <div class="relative">
        <div class="absolute -top-5 -right-5">
            <!-- Close button -->
            <button title="Close" class="text-gray-600 w-8 h-8 rounded-full flex items-center justify-center">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-4 h-4"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
            </button>
        </div>
    </div>
    <pre class="text-gray-300 whitespace-pre" id="terminal-output"></pre>
</div>
Enter fullscreen mode Exit fullscreen mode

Sprinkle a bit of JavaScript

First initalize TypedJS, targeting terminal-output:

const typed = new Typed('#terminal-output', {
    strings: [textToType],
    typeSpeed: 20,
    loop: false,
    cursorChar: '_',
});
Enter fullscreen mode Exit fullscreen mode

Next we'll write the text we want to show, it's a bit awkward but it's kind of like a mini Domain Specific Language:

const textToShow = "$ curl <span class=\"text-white\">https://app.mailpace.com/api/v1/send</span>\n -H MailPace-Server-Token: a3c4-efg6 \n -d {\n    from: awesome@developer.com,\n    to: important@users.com,\n    subject: Woah, MailPace Rocks!\n} \n\n`<span class=\"text-gray-500\">Sending...</span>`\n^250<span class=\"text-green-200\">โœ“ Email Sent!</span>";
Enter fullscreen mode Exit fullscreen mode
  • ^ followed by a number means to pause by that number of milliseconds, e.g. while simulating a network call
  • Anything wrapped in backticks is output from the terminal
  • \n is a line break
  • We we can embed <span> elements to give us basic syntax highlighting

Note that this curl example isn't working code, we just want to represent a simplified version for our viewers to understand what's going on. If we add all the pieces needed for it to work, it's not as clear what's going on.

Add some animation

Not strictly necessary, but let's add a little bounce when our users open the site, to kick start the typing:

<style>
    @keyframes softBounce {
        0%, 20%, 50%, 80%, 100% {
            transform: translateY(0);
        }
        40% {
            transform: translateY(-30px);
        }
        60% {
            transform: translateY(-5px);
        }
    }

    .terminal-window {
        animation: softBounce 1s ease-in;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

And we're done! Check out the working version here: https://mailpace.com

Top comments (2)

Collapse
 
hasanelsherbiny profile image
Hasan Elsherbiny

interesting

Collapse
 
ritter profile image
Hoasd

The idea of this article is great, but the implementation is clearly in need of improvement. Therefore, very difficult to make it work for beginners (like me).

1) Typos in variable names which rely on each other like textToType vs textToShow is especially for newbies very frustrating and difficult to figure it out
2) Missing a complete (working and tested) code example
3) Using Tailwind that way (cdn) is a bad practice.

It is not exactly helpful to show only individual code fragments without the entire code. In addition, a test with the complete code would have immediately revealed the typo error.