Start tracking your progress
Trailhead Home
Trailhead Home

Create the Session Details Web Component

In this step, you create a new web component that shows the details for a specific conference session. You also implement a simple navigation system that allows users to navigate back and forth between the session list and the session details.

Create the sessionDetails Web Component

First, let’s create the web component’s JavaScript file.

  1. Under the existing my folder, create a new folder named sessionDetails.
  2. In the sessionDetails folder, create a new file called sessionDetails.js.
  3. Implement the sessionDetails class as follows:
    import { LightningElement, api } from 'lwc';
    import { getSession } from 'data/sessionService';
    export default class SessionDetails extends LightningElement {
      session;
      @api
      set sessionId(id) {
        this._sessionId = id;
        this.session = getSession(id);
      }
      get sessionId() {
        return this._sessionId;
      }
    }

    We use the @api decorator to define the sessionId setter method as public. That way you can provide a sessionId as an attribute of the my-session-details tag. Properties annotated with @api are reactive: when their value changes, the component is automatically rerendered.

  4. Save the sessionDetails.js file.

Now let’s create the user interface in the web component template.

  1. In the sessionDetails folder, create a new file named sessionDetails.html.
  2. Implement the template as follows:
    <template>
      <template if:true={session}>
        <h2>{session.name}</h2>
        <p class="icon time">{session.dateTime}</p>
        <p class="icon room">{session.room}</p>
        <h3>Abstract</h3>
        <div class="abstract">{session.description}</div>
      </template>
    </template>
    
  3. Save the sessionDetails.html file.

Next, let’s create the web component’s CSS file to make sure everything looks good.

  1. In the sessionDetails folder, create a new file called sessionDetails.css.
  2. Define the following styles:
    :host {
      width: 100%;
      margin: 2rem;
      color: #080707;
    }
    p {
      margin: 0;
    }
    .icon {
      color: #039be5;
      background-repeat: no-repeat;
      background-size: contain;
      padding-left: 24px;
    }
    .icon.time {
      background-image: url(https://developer.salesforce.com/files/js-dev/icons/clock.svg);
      margin-top: .6rem;
    }
    .icon.room {
      background-image: url(https://developer.salesforce.com/files/js-dev/icons/location.svg);
      margin-top: .4rem;
    }
    h2 {
      font-weight: 600;
      font-size: 1.4rem;
    }
    h2 a, h2 a:visited {
      color: #039be5;
      text-decoration: none;
    }
    h2 a:hover {
      color: #017bb7;
    }
    h3 {
      font-weight: bold;
      font-size: 1.1rem;
      margin: 1.5rem 0 0.5rem 0;
    }
    .list-wrapper {
      display: flex;
      flex-direction: column;
    }
    .speaker-list {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      margin: 0 -0.5rem;
    }
  3. Save the sessionDetails.css file.

That’s it! You created a web component that displays the details for a conference session.

Add the Components to the App

To see it in action, you need to add it to the application.

  1. Open the app.html file in the app folder.
  2. Add the following tag right after the <my-session-list></my-session-list> tag:
    <my-session-details session-id={sessionId}></my-session-details>
  3. Save the app.html file.
  4. Open the app.js file.
  5. Define a property inside the App class definition:
    import { LightningElement } from 'lwc';
    
    export default class App extends LightningElement {
      sessionId;
    }
  6. Save the app.js file.

Go back to your browser, and notice that the sessionDetails component does not appear. That is because the sessionId property you just defined in app.js doesn’t point to an actual sessionId yet. In other words, the app doesn’t know which session to display. This brings up a good question: Which session should the sessionDetails component actually display? The answer is: The session that the user clicks in the sessionList component! And how does the sessionList component notify the app that a specific session was clicked? By dispatching a custom DOM event.

Wiring Everything Together

Now that you’ve created all of the different components, you need to display them in different aspects of the application and make sure that the different components react to each other.  First, let’s modify the sessionList component so it fires an event when a session is clicked.

  1. Open the sessionList.html file.
  2. Add the following attributes to the <a> tag: data-index={index} onclick={handleSessionClick}

    It should look like 

    <a key={session.id} class="session" data-index={index} onclick={handleSessionClick}>
  3. Save the sessionList.html file.
  4. Open the sessionList.js file.
  5. Add the handleSessionClick event handler to the SessionList class, right after the handleSearchKeyInput function:
    handleSessionClick(event) {
      const index = event.currentTarget.dataset.index;
      const navigateEvent = new CustomEvent('navigate', {
        detail: {
          sessionId: this.sessions[index].id
        }
      });
      this.dispatchEvent(navigateEvent);
    }
  6. Save the sessionList.js file.

Next, let’s listen to that event in the app web component.

  1. Open the app.html file.
  2. Add an onnavigate attribute on the my-session-list tag:
    <my-session-list onnavigate={handleNavigate}></my-session-list>
  3. Save the app.html file.
  4. Open the app.js file.
  5. Add the handleNavigate event handler right after sessionId;:
    handleNavigate(event) {
      this.sessionId = event.detail.sessionId;
    }
  6. Save the app.js file.

Go back to the browser, and click one of the sessions. The details for that session should now appear after the list. 

The application rendering the talk information under the session list.

Everything works fine, but scrolling to the bottom of the list to see details is not a great user experience. You could display the details to the right of the list, but that would probably not fit on mobile. In the next section you implement a basic navigation system that allows the user to navigate to different views.

Add Navigation

Navigation is an essential part of Single Page Applications. In this project, you implement a minimal navigation system using two states for the application ('list' and 'details'), and use custom events to navigate between these states.

  1. Open the app.js file.
  2. Declare a state property right after sessionId;:
    state = 'list';
  3. Modify the handleNavigate event handler to change the state of the application based on the custom navigate event values.
    handleNavigate(event) {
      this.state = event.detail.state;
      this.sessionId = event.detail.sessionId;
    }
  4. Add two getter functions that can be used in the component’s template to check the current state of the application.
    get isStateList() {
      return this.state === 'list';
    }
    get isStateDetails() {
      return this.state === 'details';
    }
  5. Save the app.js file.
  6. Open the app.html file.
  7. Wrap<my-session-list> in an if:true directive to only display it when the state of the application is 'list':
    <template if:true={isStateList}>
      <my-session-list onnavigate={handleNavigate}>
      </my-session-list>
    </template>
    
  8. Wrap<my-session-details> in an if:true directive to only display it when the state of the application is 'details':
    <template if:true={isStateDetails}>
      <my-session-details session-id={sessionId}>
      </my-session-details>
    </template>
  9. Add an onnavigate attribute on the my-session-details tag:
    <my-session-details onnavigate={handleNavigate} session-id={sessionId}>
    </my-session-details>
  10. Save the app.html file.

Next, let’s make sure we change state when selecting a session.

  1. Open the sessionList.js file.
  2. Replace the handleSessionClick event handler function with:
    handleSessionClick(event) {
      const index = event.currentTarget.dataset.index;
      const navigateEvent = new CustomEvent('navigate', {
        detail: {
          state: 'details',
          sessionId: this.sessions[index].id
        }
      });
      this.dispatchEvent(navigateEvent);
    }
  3. Save the sessionList.js file.

Next, let’s make sure users can go back to the session list.

  1. Open the sessionDetails.html file.
  2. Replace the session title <h2>{session.name}</h2> with:
  3. <h2><a href="#" onclick={handleSessionsClick}>Sessions</a> &gt; {session.name}</h2>
  4. Save the sessionDetails.html file.
  5. Open the sessionDetails.js file.
  6. Add the handleSessionsClick event handler to the sessionDetails class, right after the sessionId getter function:
    handleSessionsClick() {
      const navigateEvent = new CustomEvent('navigate', {
        detail: {
          state: 'list'
        }
      });
      this.dispatchEvent(navigateEvent);
    }
    
  7. Save the sessionDetails.js file.

Go back to the browser, and click one of the sessions. The session list now displays the details view for the clicked session. If you click the 'Sessions' link next to the session title, you go back to the session list.

View of the Session Details for Introducing Web Components

Great job! Conference attendees can see a list of sessions and navigate to the details view when they click a specific session. To put what you have learned into practice, create a final web component that displays speaker cards on the session details view.

Add Speaker Cards

First, let’s create the web component’s JavaScript file.

  1. Under the existing my folder, create a new folder named speakerCard.
  2. In the speakerCard folder, create a new file called speakerCard.js.
  3. Implement the SpeakerCard class as follows:
    import { LightningElement, api } from 'lwc';
      export default class SpeakerCard extends LightningElement {
        @api speaker;
    }
  4. Save the speakerCard.js file.

Next, let’s create the web component’s HTML template.

  1. In the speakerCard folder, create a file named speakerCard.html.
  2. Implement the template as follows:
    <template>
      <div class="card">
        <div class="header">
          <img src={speaker.pictureUrl} alt="Speaker picture">
          <div>
            <p class="title">{speaker.name}</p>
            <p class="icon email">{speaker.email}</p>
          </div>
        </div>
        {speaker.bio}
      </div>
    </template>
  3. Save the speakerCard.html file.

Next, let’s add some styles to make sure everything looks good.

  1. In the speakerCard folder, create a file named speakerCard.css.
  2. Add the following styles:
    :host {
      margin: 0.5rem;
      flex: 1;
      color: #080707;
    }
    .card {
      border: 1px solid #dddbda;
      border-radius: 0.25rem;
      padding: 1rem;
    }
    .card .header {
      display: flex;
      align-items: center;
      margin-bottom: 1rem;
    }
    .card img {
      border-radius: 50%;
      height: 5rem;
      margin-right: 1rem;
    }
    .card .title {
      font-weight: 600;
    }
    .card .icon {
      color: #039be5;
      background-repeat: no-repeat;
      background-size: contain;
      padding-left: 24px;
    }
    .card .icon.email {
      background-image: url(https://developer.salesforce.com/files/js-dev/icons/email.svg);
      margin-top: 0.4rem;
    }
    p {
      margin: 0;
    }
  3. Save the speakerCard.css file.

Add Speakers to Session Details

Finally, let’s add the speaker cards to the session details view.

  1. Open the sessionDetails.html file.
  2. Add the following markup after the abstract div:
    <h3>Speakers</h3>
      <div class="speaker-list">
        <template if:true={session.speakers}>
          <template for:each={session.speakers} for:item="speaker">
            <my-speaker-card key={speaker.id} speaker={speaker}>
            </my-speaker-card>
        </template>
      </template>
    </div>
  3. Save the sessionDetails.html file.

Go back to your browser window and click a session in the list. The session details view should now look like this, including the speaker cards.

 View of the Session Details for Web Components Patterns and Best Practices with extra cards for each session speaker

Congratulations, you’ve successfully created your first Lightning Web Component Open Source application! Check out the next project of this series where you modify the application to get the conference data from Salesforce using REST services. You don’t need to know Salesforce to perform the next project; we guide you through all the steps.

We won’t check any of your local development. Click Verify Step to complete the project.