Build an Interactive Quiz using ⚡AMP Email
benjamin
Posted on March 25, 2024
Background
Many news organizations create weekly quizzes about recent events. These organizations usually send out an email containing a link to the quiz hosted on their website. This requires users to click on the link and navigate to a landing page to play the quiz.
The Goal
Instead of leaving the inbox to play the quiz in a web browser, is it possible to create a fully playable quiz within the email? Yes, through the use of AMP email and the amp-bind
component, you can build an interactive quiz.
🛠️ Let's Start Building
The following is a step by step guide for building a short, four question AMP quiz. Scroll to the bottom to view the AMP quiz demo ⏬
🏗️ AMP Boilerplate Template
1). Start by setting up an AMP email template with the required amp-bind
script in the <head>
tag
Below is a sample AMP email boilerplate:
<!doctype html>
<html ⚡4email data-css-strict lang="en">
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<style amp4email-boilerplate>body{visibility:hidden}</style>
<style amp-custom>
h1 {
margin: 1rem;
}
</style>
</head>
<body>
<h1>Hello, I am an AMP EMAIL!</h1>
</body>
</html>
❓ Question ✅ Answer Modules
2). Create the first quiz question and corresponding choices
<h3>Question #1</h3>
<h2>How many boroughs make up New York City?</h2>
<article id="q1Question">
<button>
Four
</button>
<button>
Five
</button>
<button>
Six
</button>
<button>
Seven
</button>
</article>
3). Then create the answer module below the original choices. This module will reveal the player's correct or incorrect answer selection
<h3>Question #1</h3>
<h2>How many boroughs make up New York City?</h2>
<article id="q1Question">
<button>
Four
</button>
<button>
Five
</button>
<button>
Six
</button>
<button>
Seven
</button>
</article>
<article id="q1Answer">
<button>
Four
</button>
<button>
Five
</button>
<button>
Six
</button>
<button>
Seven
</button>
</article>
4). Apply the hidden
attribute to hide the quiz answer module
<article id="q1Answer" hidden>
...
</article>
In order to hide the question module and reveal the answer module after selecting a choice, we need to create an event handler that listens to this action.
5). Use the on
attribute to create an event handler that hides the question module and reveals the answer module after "tapping" on one of the choices
<h3>Question #1</h3>
<h2>How many boroughs make up New York City?</h2>
<article id="q1Question">
<button on="tap:q1Question.hide,q1Answer.show">
Four
</button>
<button on="tap:q1Question.hide,q1Answer.show">
Five
</button>
<button on="tap:q1Question.hide,q1Answer.show">
Six
</button>
<button on="tap:q1Question.hide,q1Answer.show">
Seven
</button>
</article>
The purpose of this event handler is to prevent users from answering the question again after making an initial selection.
Now let's reveal the correct answer and indicate through CSS styling and classes whether the selected option was correct or incorrect ⬇️
6). Use AMP.setState()
to bind a correct
or incorrect
class to each of the options
<h3>Question #1</h3>
<h2>How many boroughs make up New York City?</h2>
<article id="q1Question">
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn1Class: 'incorrect'})">
Four
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct'})">
Five
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn3Class: 'incorrect'})">
Six
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn4Class: 'incorrect'})">
Seven
</button>
</article>
7). Add the corresponding [class]
attribute to each of the options in the answer module
<h3>Question #1</h3>
<h2>How many boroughs make up New York City?</h2>
<article id="q1Question">
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn1Class: 'incorrect'})">
Four
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct'})">
Five
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn3Class: 'incorrect'})">
Six
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn4Class: 'incorrect'})">
Seven
</button>
</article>
<article id="q1Answer" hidden>
<button [class]="btn1Class || ''">
Four
</button>
<button [class]="btn2Class || ''">
Five
</button>
<button [class]="btn3Class || ''">
Six
</button>
<button [class]="btn4Class || ''">
Seven
</button>
</article>
The AMP.setState({btn2Class: 'correct', btn1Class: 'incorrect'})
action will assign the correct
CSS class through the [class]="btn2Class || ''"
expression. It will also assign the incorrect
CSS class through the [class]="btn1Class || ''"
expression. The same logic applies to the rest of the buttons.
8). Create the correct
and incorrect
classes and add the CSS styling
/* AMP.setState CLASSES */
.correct {
background-color: #3beb57;
color: #000000;
}
.incorrect {
background-color: #ff3636;
color: #ffffff;
}
Up to this point, we have created the first quiz question with four different options. When a user selects one of the options, the hidden answer module will reveal and the correct
and incorrect
class expression will render.
💯 Recording the Quiz Score
Now let's use amp-bind
to track a user's quiz score as they answer each question.
9). Use the AMP.setState()
action and the [text]
attribute to record and display a score. The state variable quizScore
will now update to the value of 1
if the correct option is selected or 0
for the incorrect options
<h3>Question #1</h3>
<h3>Your Score: <span [text]="quizScore">0</span></h3>
<h2>How many boroughs make up New York City?</h2>
<article id="q1Question">
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn1Class: 'incorrect', quizScore: 0})">
Four
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', quizScore: 1})">
Five
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn3Class: 'incorrect', quizScore: 0})">
Six
</button>
<button on="tap:q1Question.hide,q1Answer.show,AMP.setState({btn2Class: 'correct', btn4Class: 'incorrect', quizScore: 0})">
Seven
</button>
</article>
⏩ Next Quiz Question
After a quiz question is answered, let's provide a way to move onto the next question.
10). Create a "Next question" button within the hidden answer module
<article id="q1Answer" hidden>
<button [class]="btn1Class || ''">
Four
</button>
<button [class]="btn2Class || ''">
Five
</button>
<button [class]="btn3Class || ''">
Six
</button>
<button [class]="btn4Class || ''">
Seven
</button>
<button on="tap:q1Section.hide,q2Section.show">
Next question →
</button>
</article>
11). Then wrap the entire question #1 module (including the question and answer modules) in a <section>
element. Wrap the entire question #2 module using the same method
<!-- QUESTION #1 -->
<section id="q1Section">
<h3>Question #1</h3>
<h2>How many boroughs make up New York City?</h2>
...
</section>
<!-- end question #1 -->
<!-- QUESTION #2 -->
<section id="q2Section" hidden>
<h3>Question #2</h3>
<h2>What is the largest park in NYC?</h2>
...
</section>
<!-- end question #2 -->
The "Next question" button with the on="tap:q1Section.hide,q2Section.show"
event will hide question #1 and display question #2.
Repeat these steps for questions #2 and #3 to finish building the quiz. Now the quiz is completed 🙌
🕹️ AMP Quiz Demo
Below is a demo featuring a four question quiz with some added CSS styling.
⚠️ NOTE: Copy & paste the HTML tab code into the Gmail AMP Playground or the amp.dev Playground for a more accurate demo experience!
🤔 Can We Automate?
Once this AMP email quiz template is created, can weekly email sends be automated with new questions pulling in from a CORS JSON endpoint?
It is possible to pull in the text content (i.e. quiz questions and options to choose from), however, the logic determining which option is correct and which options are incorrect are built into the on
attribute and event handler.
In other words, the position of the "correct" options will always stay the same for each question due to the inline nature of the AMP logic - only the text content will change. This is not an ideal situation because users will eventually learn where the "correct" option is located regardless of the quiz question content.
Currently, the only option with this particular AMP template is to manually shuffle the <button>
elements to randomize the "correct" option 🙃.
Conclusion
A fully interactive quiz can be built entirely inside of an email by using the amp-bind
component. Individual scores can also be tracked based on the user selections.
Although there is no straightforward solution for automating this AMP quiz template, the fact that users can complete the quiz without leaving their inbox is a clear win 🏆.
Posted on March 25, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.