Introduction to the Web Interface

Welcome to the first lesson of our course on building an image generation web application with Fiber! In this course, you'll learn how to create a user-friendly web interface for an AI-powered image generation service. By the end of this course, you'll have built a complete web application that allows users to generate images based on text prompts and view their generation history.

In this first lesson, we'll focus on creating the HTML structure for our application. This structure will serve as the foundation for our user interface, providing the elements that users will interact with to generate images and view their history.

Our application will have two main sections:

  1. A "Generate Image" tab where users can enter prompts and customize their image generation.
  2. A "View History" tab where users can see their previously generated images.

Fiber can serve HTML in a couple of ways:

  • Static file serving: we place index.html, style.css, and script.js in a folder like server/static, and Fiber serves them directly.
  • Server-side templates: Fiber can be configured with a Go template engine (for example Go’s html/template, Jet, etc.) if you want to render dynamic HTML on the server.

Since our implementation uses static files, our HTML will link assets with direct paths like /style.css and /script.js, and Fiber will map those URLs to files in server/static.

Now, let's start building our HTML interface!

App File Structure

Before we start building the HTML for our image generation interface, let's take a moment to understand how our Fiber application is organized. A clear file structure helps us stay organized as our project grows in complexity.

Here's the structure we'll be working with:

Folder Responsibilities
  • handlers/: Defines Fiber routes handlers
  • services/: Contains the logic for formatting prompts and generating images using AI.
  • models/: Deals with image storage and loading of prompt templates.
  • data/: Holds reusable text templates to guide consistent image generation prompts.
  • util/: Holds our Gemini 3.1 Flash REST API wrapper
  • static/: Support the front-end UI with HTML, CSS, and JavaScript.

With this structure in mind, you'll find it easier to understand where each part of the code lives as we build out the HTML and connect it to our Fiber backend.

Serving Static Files with Fiber

Before we start creating our HTML, we need to understand how Fiber serves static files like HTML, CSS, and JavaScript to web browsers. In web development, "static files" are files that don't change dynamically - they're served exactly as they are stored on the server.

In Fiber, we use the Static method to tell the server where to find these files and how to serve them:

Let's break down what this line does:

  • The first parameter "/" is the URL path - this means when users visit the root of our website (like http://localhost:3000/), Fiber will look for files in our static directory
  • The second parameter "server/static" is the file system path - this tells Fiber where to find the files on our server
How Static File Serving Works

When you set up static file serving like this, Fiber creates a mapping between URLs and files:

  • http://localhost:3000/ → serves server/static/index.html
  • http://localhost:3000/style.css → serves server/static/style.css
  • http://localhost:3000/script.js → serves server/static/script.js

This is why in our HTML, we can reference files using simple paths like /style.css - Fiber automatically knows to look in the server/static directory.

Adding Static File Serving to Your Server

In your server.go file, you'll add the static file serving right after creating your Fiber app:

This setup allows our HTML file to load CSS and JavaScript files, and enables users to access our web interface through their browser.

Creating the Basic HTML Document Structure

Every HTML document starts with a basic structure that includes the document type declaration, the HTML root element, and the head and body sections. Let's create this structure for our image generator application.

Let's break down what each part of this code does:

  • <!DOCTYPE html> tells the browser that this is an HTML5 document.
  • <html lang="en"> is the root element of the HTML document, with "en" specifying English as the language.
  • The <head> section contains metadata about the document:
    • <meta charset="UTF-8"> specifies the character encoding for the document.
    • <meta name="viewport" content="width=device-width, initial-scale=1.0"> ensures proper scaling on mobile devices.
    • <title>AI Event Banner Generator</title> sets the title that appears in the browser tab.
    • <link rel="stylesheet" href="/style.css"> links to our CSS file. Notice how we use /style.css - this works because of our static file serving setup!

Now that we have our basic structure, let's add the content to our body section.

Building the Tab Navigation System

Our application will have two main tabs: one for generating images and another for viewing the history of generated images. Let's create the tab navigation system that will allow users to switch between these views.

In this code, we've added:

  • A <div> with the class tabs that contains two buttons, one for each tab.
  • Each button has an onclick attribute that calls a JavaScript function named openTab with the ID of the tab to open.
  • Two <div> elements with the class tab-content and IDs generate and history. These will contain the content for each tab.
  • The "history" tab content has style="display:none;" to hide it initially, showing only the "generate" tab when the page loads.

The openTab function will be defined in our JavaScript file, which we'll link at the end of our HTML document. This function will handle showing and hiding the appropriate tab content when a user clicks on a tab button.

Now, let's fill in the content for each tab.

Designing the Image Generation Form

The "Generate Image" tab will contain a form where users can enter a prompt for the image they want to generate, select an aspect ratio. Let's create this form:

Let's examine the elements in our form:

  • A container <div> to hold all the form elements.
  • An <h1> heading that displays the title of our application.
  • An <input> field where users can enter their image description (prompt).
  • A dropdown <select> menu for choosing the aspect ratio of the generated image, with options for square, widescreen, classic, and portrait formats.
  • A button that, when clicked, will call a JavaScript function named generateImage() to process the form and generate the image.
  • A loading message that will be displayed while the image is being generated. It's initially hidden with style="display: none;".
  • An empty <div> with the ID image-container where the generated image will be displayed.
Setting Up the History View

The "View History" tab will allow users to see their previously generated images. Let's create the content for this tab:

The history view is simpler than the generation form:

  • A container <div> to hold all the elements.
  • An <h1> heading that displays "Image History".
  • A button that, when clicked, will call a JavaScript function named fetchHistory() to load the user's previously generated images.
  • An empty <div> with the ID history-container where the images will be displayed.

The fetchHistory() function will be defined in our JavaScript file. It will fetch the user's image history from our backend API and display the images in the history-container div.

Connecting Everything Together

Now that we have created all the necessary HTML elements, let's connect everything together by adding the script tag at the end of our body section:

Notice how we reference /script.js - just like with our CSS file, this works because of our static file serving configuration. Fiber will automatically serve the script.js file from our server/static directory.

Browser Hot Reload

We've set up your Fiber server to use Air to re-build your server every time you make a change. You'll see this in all the examples and it makes development much easier. After the server reloads, you still need to reload your browser to see the changes and that can slow you down.

Let's add brower hot reloading using Websockets.

Websocket Handler

We can use Fiber to handle a Websocket route:

This handler accepts the WebSocket connection and waits on ReadMessage(). Since our frontend does not send messages to this socket, the call remains blocked until the connection closes, such as when the browser disconnects or the server restarts. When the server stops, the client loses the WebSocket connection, which is the signal we'll use to reload the page.

Client Reload Code

On the client, we need to connect to the /livereload websocket and add an onclose handler:

Whenever the backend re-builds and restarts the server, the frontend see the connection close. We wait 2 seconds, just to make sure the server is given time to restart, and reload the page. The connection restarts and we are ready to reload again!

Summary

In this lesson, we've created the HTML structure for our image generator application. We've set up a tab navigation system, designed a form for generating images, and created a view for displaying the image history. We've also linked our CSS and JavaScript files using direct paths (/style.css and /script.js), which work because Fiber is serving our server/static directory via app.Static(...).

Right now, our application doesn't look very appealing because we haven't added any styling yet. Additionally, the buttons don't do anything because we haven't implemented the JavaScript functions. In the next lesson, we'll add CSS to style our application and make it visually appealing. After that, we'll implement the JavaScript functions to handle user interactions and communicate with our backend API.

The HTML structure we've created serves as the foundation for our application. It defines the elements that users will interact with and provides the structure that our CSS and JavaScript will build upon. By understanding this structure and how Fiber serves it to browsers, you'll be better prepared to implement the styling and functionality in the upcoming lessons.

In the practice exercises that follow, you'll have the opportunity to modify this HTML structure and experiment with different elements to better understand how they work together. You'll also get to see how the HTML structure interacts with CSS and JavaScript to create a complete web application.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal