\#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:
```bash
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:
```html
<!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:
```html
<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:
```html
<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:
```bash
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:
![](https://i.imgur.com/Tfjd2ZX.png)
## 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](https://github.com/holochain/hc-web-client). It's Holochain's JavaScript library that helps you easily setup a [WebSocket](https://en.wikipedia.org/wiki/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:
```bash
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:
```html
<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
```html
<script type="text/javascript">
```
Make a WebSocket connection to Holochain on port 3401:
```javascript
var holochain_connection = holochainclient.connect({
url: 'ws://localhost:3401',
});
```
Add a `hello()` JavaScript function so you can call it from your HTML:
```javascript
function hello() {
```
Wait for Holochain to connect and then make a zome call:
```javascript
holochain_connection.then(({callZome, close}) => {
```
Call the `hello_holo` zome function in the `hello` zome running on the `test-instance` instance:
```javascript
callZome('test-instance', 'hello', 'hello_holo')({args: {}})
```
Log the result in the browser's console:
```javascript
.then((result) => console.log(result))
})
}
```
Close the script tag:
```html
</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:
```diff
- <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:
```bash
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:
![](https://i.imgur.com/vhTaH0W.png)
> 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:
```html
<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:
```javascript
function show_output(result) {
```
Get the element that you'll be inserting the output into:
```javascript
var span = document.getElementById('output');
```
Parse the zome function result as JSON:
```javascript
var output = JSON.parse(result);
```
Set the contents of the element to the zome function result:
```javascript
span.textContent = ' ' + output.Ok;
}
```
Finally, update the `hello` function to call your new `show_output` function instead of `console.log()`.
```diff
- result => console.log(result),
+ result => show_output(result),
```
<script id="asciicast-oTse2TbmFJImX9Ra04cUc7xRo" src="https://asciinema.org/a/oTse2TbmFJImX9Ra04cUc7xRo.js" async data-autoplay="true" data-loop="true"></script>
## 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:
![](https://i.imgur.com/FMxeMx0.png)
Now press the **Say Hello** button and you get your response:
![](https://i.imgur.com/mDBaVlD.png)
Well done! You have a working GUI that can talk to your Holochain app.