diff --git a/src/gapfill-select.js b/src/gapfill-select.js
new file mode 100644
index 0000000000000000000000000000000000000000..715af47ddda68af5e8eed6278efa8c608d57046b
--- /dev/null
+++ b/src/gapfill-select.js
@@ -0,0 +1,69 @@
+/**
+ * Custom SurveyJS question type for a "fill-in-the-gaps" text,
+ * with a drop-down selection of choices for each
+ */
+export const gapfillSelectWidget = {
+    name: "gapfill-select",
+    title: "Gap-Fill Text (Select)",
+    /**
+     * This function should return true when the widget and all needed resources
+     * are loaded
+     */
+    widgetIsLoaded: function () {
+        return true;
+    },
+    /**
+     * This function should return true if the widget should be applied to the question */
+    isFit: function (question) {
+        return question.getType() === this.name;
+    },
+    init() {
+        //Register a new type using the empty question as the base.
+        Survey.Serializer.addClass(this.name, [], null, "empty");
+    },
+    /** Static HTML template rendered by SurveyJS */
+    htmlTemplate: '<p id="gapfill-container"><template id="template-select"><select class="sd-input sd-dropdown inline-dropdown"><option selected/></select></template></p>',
+    /**
+     * Function called after the HTML template is rendered. This time we actually have the `question` object
+     * and the `el` element, to build the question according to the JSON
+     */
+    afterRender: function (question, el) {
+        // The gap-fill text is made of segments, which are either plain pieces
+        // of text (strings) or "gaps" with a few options to select (string arrays).
+        // We append these to build the text, turning strings into <span>s and
+        // gaps into <select> dropdowns
+        let nbGaps = 0;
+        const segmentElems = new DocumentFragment(); // a bit faster than mutating the DOM all the time
+        const selectTemplate = document.getElementById("template-select").content.firstChild;
+        for (const segment of question.jsonObj.segments) {
+            let segmentElem;
+            if (typeof segment === 'string' || segment instanceof String) {
+                segmentElem = document.createElement("span");
+                segmentElem.innerText = segment;
+            } else if (segment instanceof Array) {
+                // It's a gap
+                // Create the <select> element
+                segmentElem = selectTemplate.cloneNode(true);
+                segmentElem.setAttribute("data-index", nbGaps); // The node knows its index
+                // Create and append options
+                for (const opt of segment) {
+                    let optionElem = document.createElement("option");
+                    optionElem.innerText = opt;
+                    segmentElem.appendChild(optionElem);
+                }
+                // Add listener to update the question's value when the selector's value changes
+                segmentElem.addEventListener("change", (e) => {
+                    // The select node knows its index, therefore is able to update the question value at the correct index
+                    question.value[parseInt(e.target.getAttribute("data-index"))] = e.target.value;
+                });
+                nbGaps++;
+            }
+            // Add segment
+            segmentElems.appendChild(segmentElem);
+        }
+        // Initialize question value array
+        question.value = new Array(nbGaps);
+        // Finally add everything to the DOM
+        el.appendChild(segmentElems);
+    },
+};
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..128b79302a21ed1a04001f9f96ecdf00602888c4
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Survey-Quizgets example</title>
+
+    <link rel="stylesheet" href="style.css">
+    <!-- SurveyJS & dependencies-->
+    <script defer src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"
+            type="text/javascript"></script>
+    <link href="https://unpkg.com/survey-jquery/defaultV2.min.css" rel="stylesheet" type="text/css">
+    <script defer src="https://unpkg.com/survey-jquery/survey.jquery.min.js" type="text/javascript"></script>
+
+    <script src="index.js" type="module"></script>
+</head>
+<body>
+<div id="surveyContainer"></div>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..c4cf95d4c09844deef6c84d5267e2503664cd840
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,14 @@
+import {json} from "./json.js"
+import {gapfillSelectWidget} from "./gapfill-select.js";
+
+window.addEventListener('load', main)
+
+function main() {
+    // Register our custom question types
+    Survey.CustomWidgetCollection.Instance.add(gapfillSelectWidget, gapfillSelectWidget.name);
+
+    let survey = new Survey.Model(json);
+
+    // Inflate the survey in the page
+    $("#surveyContainer").Survey({model: survey});
+}
diff --git a/src/json.js b/src/json.js
new file mode 100644
index 0000000000000000000000000000000000000000..a1ed56016ae7637c9223f339892e11c7c165a013
--- /dev/null
+++ b/src/json.js
@@ -0,0 +1,42 @@
+export const json = {
+    elements: [
+        {
+            type: "gapfill-select",
+            name: "pg20",
+            title: "The greatest song in the world",
+            segments: [
+                "šŸŽ¶\nWe're no strangers to ",
+                ["code", "love", "life"],
+                "\nYou ",
+                ["Node.js", "know the rules", "like apples"],
+                " and so do I",
+                "\nšŸŽ¤ [...]",
+                "\nNever gonna ",
+                [
+                    "give you up",
+                    "let you down",
+                    "make you cry",
+                    "say goodbye",
+                ],
+                "\nNever gonna ",
+                [
+                    "run around",
+                    "tell a lie",
+                ],
+                " and ",
+                [
+                    "desert",
+                    "hurt"
+                ],
+                " you"
+            ],
+            correctAnswer: [
+                "love",
+                "know the rules",
+                "give you up",
+                "run around",
+                "desert"
+            ]
+        }
+    ]
+};
\ No newline at end of file