---
id: 66ebd4ae2812430bb883c787
title: Build an Event Hub
challengeType: 25
dashedName: lab-event-hub
demoType: onClick
---

# --description--

In this lab you will utilize the semantic HTML elements to create the structure of a web page. You'll add content and images to make it look like a real event hub.

**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.

**User Stories:**

1. You should have a `header` element.
1. Inside the `header` element, you should have an `h1` element that contains the text `Event Hub`, and a `nav` element.
1. Inside the `nav` element, you should have an unordered list of two items containing links to different sections of the page. The first item should have the text `Upcoming Events`, and the second item should have the text `Past Events`.
1. Each link should be represented by an `a` element with an `href` attribute that links to the corresponding section of the page, `#upcoming-events` and `#past-events` respectively.
1. You should have a `main` element that contains the different sections of the page.
1. Inside the `main` element, you should have two `section` elements.
1. The first `section` element should have an `id` attribute with the value `upcoming-events`
1. Inside the `#upcoming-events` section, you should have:
   
   - An `h2` element with the text `Upcoming Events`.
   - Two `article` elements. Each article should represent an event, and it should have :
      - An `h3` element for the event title.
      - A `p` element for the event description. You can add a date at the bottom if you like.

1. The second `section` element should have an `id` attribute with the value `past-events`.
1. Inside the `#past-events` section, you should have:

   - An `h2` element with the text `Past Events`.
   - Two `article` elements. Each article element should represent a past event, and it should have:
     - An `h3` element for the event title, 
     - A `p` element for the event description. You can add a date at the bottom if you like.
     - An image element with the `src` attribute pointing to an image file and the `alt` attribute with a description of the image.

**Note:** You can use any text for the event descriptions and dates. You can use the following image URLs for the images if you like:

- `https://cdn.freecodecamp.org/curriculum/labs/past-event1.jpg`.
- `https://cdn.freecodecamp.org/curriculum/labs/past-event2.jpg`.

# --hints--

You should have a `header` element.

```js
assert.isNotNull(document.querySelector("header"));
```

Your `header` element should come after the opening `body` tag.

```js
assert.equal(document.querySelector("body")?.firstElementChild?.tagName, "HEADER");
```

Inside the `header` element, you should have an `h1` element that contains the text `Event Hub`.

```js
const h1Element = document.querySelector('header h1');
assert.strictEqual(h1Element?.innerText.trim(), "Event Hub");
```

Inside the `header` element, after the `h1` element, you should have a `nav` element.

```js
assert.isNotNull(document.querySelector("header>h1+nav"));
```

Your `nav` element should contain an unordered list of two items.

```js
const liElements = document.querySelectorAll('header nav>ul>li');

assert.isNotNull('header nav>ul');
assert.strictEqual(liElements.length, 2);
```

The first item in the unordered list should be a link.

```js
const firstLink = document.querySelectorAll('header nav ul li a')[0];
assert.exists(firstLink);
```

The second item in the unordered list should be a link.

```js
const secondLink = document.querySelectorAll('header nav ul li a')[1];
assert.exists(secondLink);
```

The text of the first item in the unordered list should be `Upcoming Events`.

```js
const firstLink = document.querySelectorAll('header nav>ul>li>a')[0];
assert.strictEqual(firstLink.innerText.trim(), "Upcoming Events");
```

The first item in the unordered list should have the `href` set to `#upcoming-events`.

```js
const anchorElement = document.querySelectorAll("header nav>ul>li>a")[0];
const hrefAttribute = anchorElement?.getAttribute("href");
assert.strictEqual(hrefAttribute, "#upcoming-events");
```

The text of the second item in the unordered list should be `Past Events`.

```js
const secondLink = document.querySelectorAll('header nav>ul>li>a')[1];
assert.strictEqual(secondLink.innerText.trim(), "Past Events");
```

The second item in the unordered list should have the `href` set to `#past-events`.

```js
const anchorElement = document.querySelectorAll("header nav>ul>li>a")[1];
const hrefAttribute = anchorElement?.getAttribute("href");
assert.strictEqual(hrefAttribute, "#past-events");
```

You should have a `main` element after the `header` element closing tag.

```js
const mainElement = document.querySelector("body>header+main");
assert.isNotNull(mainElement);
```

Inside the `main` element, you should have two `section` elements.

```js
const sectionElements = document.querySelectorAll('body>header+main>section');
assert.strictEqual(sectionElements.length, 2);
```

Your first `section` element should have an `id` attribute with the value `upcoming-events`.

```js
const firstSection = document.querySelectorAll('body>header+main>section')[0];
const idAttribute = firstSection?.getAttribute("id");
assert.strictEqual(idAttribute, "upcoming-events");
```

Your second `section` element should have an `id` attribute with the value `past-events`.

```js
const secondSection = document.querySelectorAll('body>header+main>section')[1];
const idAttribute = secondSection?.getAttribute("id");
assert.strictEqual(idAttribute, "past-events");
```

Inside the `#upcoming-events` section, you should have an `h2` element with the text `Upcoming Events`.

```js
const h2Element = document.querySelector('#upcoming-events h2');
assert.strictEqual(h2Element?.innerText.trim(), "Upcoming Events");
```

Inside the `#upcoming-events` section, you should have two `article` elements below the `h2` element.

```js
const articleElements = document.querySelectorAll('#upcoming-events h2 ~ article');
assert.strictEqual(articleElements.length, 2);
```

Both of the `article` elements inside the `#upcoming-events` section should have an `h3` element for the event title.

```js
const h3Elements = document.querySelectorAll('#upcoming-events article h3');
assert.strictEqual(h3Elements.length, 2);
```

Both of the `article` elements inside the `#upcoming-events` section should have a paragraph element for the event description.

```js
const articles = document.querySelectorAll('#upcoming-events article');
assert.isNotEmpty(articles);
articles.forEach(article => {
    assert.isAtLeast(article.querySelectorAll('h3 ~ p').length, 1);
});
```

Inside the `#past-events` section, you should have an `h2` element with the text `Past Events`.

```js
const h2Element = document.querySelector('#past-events h2');
assert.strictEqual(h2Element?.innerText.trim(), "Past Events");
```

Inside the `#past-events` section, you should have two `article` elements below the `h2` element.

```js
const articleElements = document.querySelectorAll('#past-events h2 ~ article');
assert.strictEqual(articleElements.length, 2);
```

Both of the `article` elements inside the `#past-events` section should have an `h3` element for the event title.

```js
const h3Elements = document.querySelectorAll('#past-events article h3');
assert.strictEqual(h3Elements.length, 2);
```

Both of the `article` elements inside the `#past-events` section should have a paragraph element for the event description.

```js
const articles = document.querySelectorAll('#past-events article');
assert.isNotEmpty(articles);
articles.forEach(article => {
    assert.isAtLeast(article.querySelectorAll('h3 ~ p').length, 1);
});
```

Both of the `article` elements inside the `#past-events` section should have an image element.

```js
const imgElements = document.querySelectorAll('#past-events article img');
assert.strictEqual(imgElements.length, 2);
```

Both of the image elements inside the `#past-events` section should have the `src` attribute pointing to an image file.

```js
const imgElements = document.querySelectorAll('#past-events article img');
assert.strictEqual(imgElements.length, 2);

for (let img of imgElements) {
    assert.exists(img.getAttribute("src"));
}
```

Both of the image elements inside the `#past-events` section should have the `alt` attribute with a description of the image.

```js
const imgElements = document.querySelectorAll('#past-events article img');
assert.strictEqual(imgElements.length, 2);

for (let img of imgElements) {
    assert.exists(img.getAttribute("alt"));
}
```

Each `h3` element should have the event title.

```js
const eventTitles = document.querySelectorAll('h3');
assert.isNotEmpty(eventTitles);
eventTitles.forEach((eventTitle => assert.isNotEmpty(eventTitle.innerText.trim())));
```

Each `p` element should have the event description.

```js
const eventDescriptions = document.querySelectorAll('p');
assert.isNotEmpty(eventDescriptions);
eventDescriptions.forEach((eventDescription => assert.isNotEmpty(eventDescription.innerText.trim())));
```

# --seed--

## --seed-contents--

```html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>Event Hub</title>
</head>

<body>

</body>

</html>
```

# --solutions--

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Event Hub</title>
</head>
<body>
    <header>
        <h1>Event Hub</h1>
        <nav>
            <ul>
                <li><a href="#upcoming-events">Upcoming Events</a></li>
                <li><a href="#past-events">Past Events</a></li>
            </ul>
        </nav>
    </header>
    <main>
        <section id="upcoming-events">
            <h2>Upcoming Events</h2>
            <article>
                <h3>AI & Machine Learning Conference 2024</h3>
                <p>Join us for a deep dive into the latest advancements in artificial intelligence and machine learning. Industry leaders will share insights and case studies on how AI is transforming various sectors.</p>
                <p>Date: August 10, 2024</p>
            </article>
            <article>
                <h3>Web Development Bootcamp</h3>
                <p>A hands-on workshop designed for developers looking to enhance their skills in modern web technologies including React, Node.js, and GraphQL. Perfect for both beginners and experienced developers.</p>
                <p>Date: September 5, 2024</p>
            </article>
        </section>
        <section id="past-events">
            <h2>Past Events</h2>
            <article>
                <h3>Cybersecurity Summit 2024</h3>
                <p>An event focusing on the latest trends and threats in cybersecurity. Experts discussed strategies for protecting data and ensuring privacy in an increasingly digital world.</p>
                <p>Date: June 15, 2024</p>
                <img src="https://cdn.freecodecamp.org/curriculum/labs/past-event1.jpg" alt="Image from Cybersecurity Summit 2024">
            </article>
            <article>
                <h3>Blockchain Expo 2024</h3>
                <p>A comprehensive event covering the future of blockchain technology. Topics included decentralized finance (DeFi), smart contracts, and the impact of blockchain on various industries.</p>
                <p>Date: July 20, 2024</p>
                <img src="https://cdn.freecodecamp.org/curriculum/labs/past-event2.jpg" alt="Image from Blockchain Expo 2024">
            </article>
        </section>
    </main>
</body>
</html>
```

