#S:MODE=test #S:EXTERNAL=rust=hello_gui.rs #S:EXTERNAL=javascript=hello_gui.js=test

Hello GUI

Welcome to the first GUI tutorial. So far you have interacted with your zome using curl or hc test, but that's not as nice as having a GUI. Today you will learn how to interact with a Holochain app using a super simple web page.

Create the HTML page

You will need somewhere for all your GUI code to live. This will be a different piece of software to your Holochain zome code. So choose somewhere outside your Holochain application.

Create a folder for our GUI to live in:

cd holochain/coreconcepts
mkdir gui
cd gui

Create a new file called index.html in your favourite editor. It should live at gui/index.html. Start by adding a simple HTML template to index.html.

Add this modern template:

<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />

    <title>Hello GUI</title>
    <meta name="description" content="GUI for a Holochain app" />
  </head>

  <body>
  </body>
</html>

Inside the <body> tag add a button:

  <button type="button">Say Hello</button>

To make things a bit nicer on the eyes you can add the water.css stylesheet.

Add this water.css link inside the <head> tag:

    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css"
    />

Run a simple server

??? question "Your index.html should now look like:" ```html <!DOCTYPE html>

โ€‹โ€‹โ€‹โ€‹<html lang="en">
โ€‹โ€‹โ€‹โ€‹  <head>
โ€‹โ€‹โ€‹โ€‹    <meta charset="utf-8" />

โ€‹โ€‹โ€‹โ€‹    <title>Hello GUI</title>
โ€‹โ€‹โ€‹โ€‹    <meta name="description" content="GUI for a Holochain app" />
โ€‹โ€‹โ€‹โ€‹    <link
โ€‹โ€‹โ€‹โ€‹      rel="stylesheet"
โ€‹โ€‹โ€‹โ€‹      href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css"
โ€‹โ€‹โ€‹โ€‹    />
โ€‹โ€‹โ€‹โ€‹  </head>

โ€‹โ€‹โ€‹โ€‹  <body>
โ€‹โ€‹โ€‹โ€‹    <button type="button">Say Hello</button>
โ€‹โ€‹โ€‹โ€‹  </body>
โ€‹โ€‹โ€‹โ€‹</html>
โ€‹โ€‹โ€‹โ€‹```

Enter the nix-shell to make sure you have all the dependencies available:

nix-shell https://holochain.love

Once that is all up and running, you can fire up a simple server:

!!! note "Run in nix-shell" bash python -m SimpleHTTPServer

And go have a look in your browser at http://0.0.0.0:8000/. You will see something like this:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More โ†’

hc-web-client

Time to communicate with the app that you built in the previous tutorials. To make this easy you can use the hc-web-client. It's Holochain's JavaScript library that helps you easily setup a WebSocket connection to your app.

Why WebSocket instead of HTTP?

Having a WebSocket connection open allows your app to send messages to your GUI. While we are not doing that today, it's good to get familiar with this process.

To make this process easy we have precompiled a version of the hc-web-client for you.

Download it here, then unzip it and stick it in the root of your GUI directory:

unzip hc-web-client.zip

The files should live here:

gui/hc-web-client/hc-web-client-0.5.1.browser.min.js
gui/hc-web-client/hc-web-client-0.5.1.browser.min.js.map

Once that's done you can easily link to the compiled js file by adding this script tag inside your body tag:

    <script
      type="text/javascript"
      src="hc-web-client/hc-web-client-0.5.1.browser.min.js"
    ></script>

Call the zome function

Now that you have linked the hc-web-client.js library you can make a simple zome call with some vanilla JavaScript.

Add this function inside your <body> tag: #S:INCLUDE,MODE=gui

    <script type="text/javascript">

Make a WebSocket connection to Holochain on port 3401:

      var holochain_connection = holochainclient.connect({
        url: 'ws://localhost:3401',
      });

Add a hello() JavaScript function so you can call it from your HTML:

      function hello() {

Wait for Holochain to connect and then make a zome call:

        holochain_connection.then(({callZome, close}) => {

Call the hello_holo zome function in the hello zome running on the test-instance instance:

      callZome('test-instance', 'hello', 'hello_holo')({args: {}})

Log the result in the browser's console:

          .then((result) => console.log(result))
        })
      }

Close the script tag:

    </script>

This hello function will connect to your app through WebSocket on port 3401, call the hello zome function, and print the result to your browser's console.

Let's make your button call this function by adding an onclick event handler.

Add this button inside the <body> tag:

-  <button type="button">Say Hello</button>
+  <button onclick="hello()" type="button">Say Hello</button>

Run your app

??? question "Check your index.html:" ```html <!DOCTYPE html>

โ€‹โ€‹โ€‹โ€‹<html lang="en">
โ€‹โ€‹โ€‹โ€‹  <head>
โ€‹โ€‹โ€‹โ€‹    <meta charset="utf-8" />

โ€‹โ€‹โ€‹โ€‹    <title>Hello GUI</title>
โ€‹โ€‹โ€‹โ€‹    <meta name="description" content="GUI for a Holochain app" />
โ€‹โ€‹โ€‹โ€‹    <link
โ€‹โ€‹โ€‹โ€‹      rel="stylesheet"
โ€‹โ€‹โ€‹โ€‹      href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css"
โ€‹โ€‹โ€‹โ€‹    />
โ€‹โ€‹โ€‹โ€‹  </head>

โ€‹โ€‹โ€‹โ€‹  <body>
โ€‹โ€‹โ€‹โ€‹    <button onclick="hello()" type="button">Say Hello</button>
โ€‹โ€‹โ€‹โ€‹    <script
โ€‹โ€‹โ€‹โ€‹      type="text/javascript"
โ€‹โ€‹โ€‹โ€‹      src="hc-web-client/hc-web-client-0.5.1.browser.min.js"
โ€‹โ€‹โ€‹โ€‹    ></script>
โ€‹โ€‹โ€‹โ€‹    <script type="text/javascript">
โ€‹โ€‹โ€‹โ€‹      var holochain_connection = holochainclient.connect({
โ€‹โ€‹โ€‹โ€‹        url: 'ws://localhost:3401',
โ€‹โ€‹โ€‹โ€‹      });
โ€‹โ€‹โ€‹โ€‹      function hello() {
โ€‹โ€‹โ€‹โ€‹        holochain_connection.then(({callZome, close}) => {
โ€‹โ€‹โ€‹โ€‹      callZome('test-instance', 'hello', 'hello_holo')({args: {}})
โ€‹โ€‹โ€‹โ€‹          .then((result) => console.log(result))
โ€‹โ€‹โ€‹โ€‹        })
โ€‹โ€‹โ€‹โ€‹      }
โ€‹โ€‹โ€‹โ€‹    </script>
โ€‹โ€‹โ€‹โ€‹  </body>
โ€‹โ€‹โ€‹โ€‹</html>
โ€‹โ€‹โ€‹โ€‹```

To make a call from the GUI, your Holochain app must be running. So open up a new terminal window, navigate to the app you built in the previous tutorials, and enter the nix-shell:

cd holochain/core_concepts/cc_tuts
nix-shell https://holochain.love

Now run your app:

!!! note "Run in nix-shell" Package the app: bash hc package Run the server on port 3401: bash hc run -p 3401

Make a zome call

In your other terminal window (the one with the GUI code), start the SimpleHTTPServer if it's not still running:

!!! note "Run in nix-shell" bash python -m SimpleHTTPServer

Open up your browser and head to 0.0.0.0:8000 (or refresh the page if it's already open). The page will look the same.

Open you your developer console and click the button. You should see something like this:

I'm using Firefox so this might look a little different depending on your browser

Woohoo! You have made a call to your Holochain app using a GUI.

Render the output

It would be nicer to see the result of the hello_holo call on the page. So let's add a somewhere to show it.

Add the following HTML below the button:

    <div>Response: <span id="output"></span></div>

The id="output" is what we will use to update this element from a JavaScript function.

Add the following lines below you hello function.

Add an show_output function that takes the result:

      function show_output(result) {

Get the element that you'll be inserting the output into:

        var span = document.getElementById('output');

Parse the zome function result as JSON:

        var output = JSON.parse(result);

Set the contents of the element to the zome function result:

        span.textContent = ' ' + output.Ok;
      }

Finally, update the hello function to call your new show_output function instead of console.log().

-            result => console.log(result),
+            result => show_output(result),

Test the output works

Head over to 0.0.0.0:8000 in your web browser (you might need to refresh) and you should see this:

Now press the Say Hello button and you get your response:

Well done! You have a working GUI that can talk to your Holochain app.