Welcome to the Intermediate DataDevQuest challenge for September 2025! This month we’re focusing on harnessing the power of the Tableau Embedding API (formerly, the JavaScript API), which allows you to make your Tableau content live seamlessly within your external application.
In the Beginner challenge, we learned how to embed Tableau content using the API and give the user a visual indication that the viz was loaded up and ready to go. Let’s take things even further now and add some back-and-forth interactivity!
An understanding of JavaScript basics will be very helpful in these challenges, but certainly isn’t required.
Note: We’re focusing on embedding content with the full API here, but there are certainly use cases where iframe embedding will be perfectly sufficient. Just know that this method will result in the loss of bi-directional interactivity.
Challenge Overview
Objective:
Add your content using the Embedding API and once it’s ready to go (via the FirstInteractive event listener) enable the user to interact with the viz and your page/application, having them pass events and data to one another.
This example shows you some of the things you might consider:
Why this challenge?
Embedding Tableau content in your application or website is a great way to harness the power of the tool, while also creating custom/bespoke experiences for your users. Imagine you have a central portal that allows users to perform several actions related to their duties, but you also want your Tableau insights to be front and center!
This challenge will help you learn how to meld your Tableau Content and your application/webpage into a singular experience where everything the user can interact with responds in harmony — allowing you to create truly bespoke user experiences that would never be possible with Tableau alone!
We can’t wait to see what you come up!
Learning Goals
- Familiarize yourself with the Embedding API capabilities
- Embed a Tableau View or Dashboard
- Using JavaScript and event listeners, allow the user to interact with both the embedded viz and elements of your app which communicate with each other to make the magic happen!
Submission Guidelines
- Source Code: Publish your project publicly in your GitHub profile
- Add README: Include any setup instructions and describe how to run the program.
- Video of Solution: Include a video of your solution in the README file. You can publish it on YouTube and embed the iframe, or save the video file in the repository’s root directory
- Comments: Ensure your code is well-commented
- Submission: Submit your challenge in the following forms
Additional Resources
- Tableau Embedding API Official Documentation
- Embedding API Reference
- Salesforce Tableau Embedding API Playground (start here if you’re new!)
Getting Started
1. Copy/paste the HTML and CSS examples below to files named index.html, styles.css and funcs.js (or use your own!)
2. You will need to serve up the page with an HTML server — if you’re using VS Code, this is super easy! Just right click on the file and select “Open with Live Server”

3. If this is your first time using the Embedding API, I strongly recommend you start with the Tableau Embedding Playground! It will show you how to setup your script imports and create your first EventListener — which you’ll need to complete this challenge.
Example code:
<!DOCTYPE html>
<html lang="en" data-bs-theme="dark" class="html-height">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Custom CSS -->
<link rel="stylesheet" href="styles.css">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css">
<title>DataDevQuest - DDQ2025-09 - Embedding: Intermediate</title>
</head>
<body class="body-height">
<!-- Navbar -->
<nav class="navbar bg-body-secondary">
<div class="container-fluid">
<a class="navbar-brand"><i class="bi bi-globe-americas-fill pe-3"></i>My Application or Website </a>
<div id="loadingSpinner">
<div class="spinner-border spinner-border-sm loading-text" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<span class="ms-2 loading-text">Tableau content is loading...</span>
</div>
<div 