Creating Landing Page

Introduction

In the previous lesson, you learned how to use Codex to set up an Express project with TypeScript and create a dice - rolling api endpoint. Now, let's build on that foundation by adding a user - friendly landing page to your Express app. In this lesson, you will use Codex to create a new route handler for the home page, serve an HTML template, build a minimal interactive frontend, and enhance the user experience with modern UI features. By the end, you'll have a polished landing page that lets users roll dice and see results instantly.

Creating the Landing Page Route Handler

Let's start by adding a new route handler for the landing page and serving an HTML page from the root path (/). This is a common pattern in Express: you create a route handler function, then serve HTML content to the browser.

First, you can ask Codex to create a new route in your Express app. Here's a prompt you might use:

plaintext
Create a GET route handler for '/' in index.ts that sends an HTML file located at 'public/index.html'.

This prompt tells Codex exactly what you want: a route for the home page that serves a static HTML file. Codex will generate the route handler, import the necessary modules like path, and use res.sendFile().

Next, you need to configure Express to serve static files from a public directory. You can instruct Codex with a prompt like:

plaintext
Add middleware to serve static files from a 'public' directory using express.static().

This tells Codex to add the static file middleware to your Express app, which will allow you to serve CSS, JavaScript, and other assets alongside your HTML. Make sure this middleware is added before your routes so that static files are served first.

By breaking your instructions into clear, single - purpose prompts, you help Codex generate accurate and maintainable code. Your existing /roll/ api endpoint will remain functional, and now you'll have a home page route as well.

Setting Up HTML File Structure

Before building the template, let's set up the proper file structure for serving HTML in Express. Unlike Django's template system, Express doesn't enforce a specific directory structure, so we'll use a straightforward approach.

You can ask Codex to help set this up:

plaintext
Create a 'public' directory in the project root if it doesn't exist, and create an empty index.html file inside it.

This creates a clear separation between your server code (TypeScript files) and your frontend assets (HTML, CSS, JavaScript). The public directory is a common convention in Express apps for serving static content directly to the browser.

Now your project structure should look something like this:

project-root/
├── src/
│   └── index.ts
├── public/
│   └── index.html
└── package.json

This structure keeps your code organized and makes it easy to add more static assets like stylesheets or client - side JavaScript files later.

Building a Minimal Interactive Template

Now that you have a route handler and file structure, let's create the HTML for your landing page. The goal is to let users pick how many dice to roll and how many sides each die has, then see the results.

Start with a prompt like this:

plaintext
Create the file public/index.html with:
- two inputs implemented as range sliders:
  - count: input type="range" min="1" max="10" value="3" with a live badge showing the number
  - sides: input type="range" min="2" max="20" value="6" with a live badge
- quick-select buttons ("chips") for counts [1,2,3,5,10] and sides [4,6,8,10,12,20]
- a submit button that triggers fetch('/roll/?count=...&sides=...')
- loading state (disable button + 'Rolling…' text)
- an inline error div and a results div with aria-live="polite"
- include a <script> tag with all JavaScript inline in the HTML

Let's break down what this prompt does:

  • It specifies the file path and the main elements you want in the HTML.
  • It describes the form controls: two range sliders for count and sides, each with a live - updating badge.
  • It asks for quick - select chips for common values, making it easy for users to pick popular options.
  • It requests a submit button that uses JavaScript's fetch to call your /roll/ api and display the results.
  • It includes a loading state, an error area, and a results area with aria - live for accessibility.
  • It specifies that JavaScript should be inline, keeping everything in one file for simplicity.

Since we're using plain HTML (not a template engine like EJS or Pug), all the HTML markup, CSS, and JavaScript will live in a single index.html file. This keeps things simple and doesn't require any additional dependencies.

By being specific about the ui elements and their behaviors, you help Codex generate an HTML page that is both functional and user - friendly.

Improving User Experience with Codex

Once you have the basic HTML template, you can use Codex to further enhance the user experience. Here are some focused prompts and explanations for each improvement:

1. Live - updating value badges for sliders

You want the number next to each slider to update as the user moves it. You can prompt Codex like this:

plaintext
Add JavaScript event listeners to update the count and sides badges live as the sliders move.

This tells Codex to add input event listeners to the range sliders and update the badge text in real time using dom manipulation.

2. Quick - select chips for common values

To make it easy for users to pick common dice counts or sides, you can use chips. Here's a prompt:

plaintext
Add click handlers to the count and sides chips so that clicking a chip sets the corresponding slider value and updates the badge.

This ensures that when a user clicks a chip, the slider position and badge update to match, providing a seamless experience.

3. Loading state and inline error display

To give feedback while the dice are rolling and to handle errors, you can use:

plaintext
When the user clicks Roll, disable the button and show 'Rolling…' until the fetch completes. If there is an error, show it in the error div and clear it on the next roll attempt.

This prompt helps Codex add logic to disable the button during the fetch, show a Rolling… message, and display errors if something goes wrong (like network issues or invalid responses).

4. Accessibility with aria - live

To make sure screen readers announce the results, you can say:

plaintext
Set aria-live="polite" on the results area so updates are announced to screen readers automatically.

This small addition makes your app more accessible to all users, ensuring that screen reader users get immediate feedback when the dice results appear.

By giving Codex clear, focused prompts for each enhancement, you can build a modern, interactive, and accessible landing page step by step. Each improvement adds polish and makes your app more professional.

Summary and What's Next

In this lesson, you learned how to use Codex to add a landing page to your Express app, create a route handler for the home page, set up static file serving, build a minimal interactive HTML page, and enhance the user experience with live badges, quick - select chips, loading states, error handling, and aria - live accessibility features. These skills will help you create user - friendly web applications quickly and efficiently.

In the next lesson, you'll extend your api to support dice notation (like 2d6 + 3) and add input validation with proper error handling using TypeScript types and Express middleware.

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