A library of premium, interactive web components designed for English Language Teaching (ELT) and language learning blogs.
Explore interactive live demos, generate AI content with Gemini Gems, or copy embed code for Google Sites & WordPress.
Interactive story reader with word highlighting, text-to-speech, and memory matching activities.
Gamified grammar practice with lives, multiple-choice, and sentence scrambling challenges.
Collaborative multi-player activity for communication practice or single-player mode with AI partner.
Comprehensive listening lesson component with vocabulary preview, dialogue, and comprehension quiz.
Fast-paced review game where students score points based on how quickly they can answer questions.
Multi-stage level placement test powered by JSON configuration where students unlock subsequent levels by meeting target score cutoffs.
Multi-chapter reader with integrated Text-to-Speech, translation toggles, and comprehension checks.
Practice speaking with native audio comparison, minimal pair discrimination, and sentence scrambles.
Legacy quiz component. Maintained for support of existing quizzes. For new tests, use <tj-test>.
Zero setup required. Paste Gemini AI output, visually edit questions, configure teacher codes, and copy ready-to-embed blog code.
Complete CDN setup, global features, component attributes, and site builder integration instructions.
Include these script tags in your site's header or custom HTML block to enable all components:
<!-- Components -->
<script type="module" src="https://scripts.teacherjake.com/tj-reader.js"></script>
<script type="module" src="https://scripts.teacherjake.com/tj-grammar-hearts.js"></script>
<script type="module" src="https://scripts.teacherjake.com/tj-info-gap.js"></script>
<script type="module" src="https://scripts.teacherjake.com/tj-listening.js"></script>
<script type="module" src="https://scripts.teacherjake.com/tj-speed-review.js"></script>
<script type="module" src="https://scripts.teacherjake.com/tj-quiz-element.js"></script>
<script type="module" src="https://scripts.teacherjake.com/tj-chapter-book.js"></script>
<script type="module" src="https://scripts.teacherjake.com/tj-pronunciation.js"></script>
<script type="module" src="https://scripts.teacherjake.com/tj-progressive-test.js"></script>
<!-- Required Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;600;800&family=Inter:wght@400;600&display=swap" rel="stylesheet">
Students enter a nickname and student number to generate a modal report card for score reporting and teacher screenshot submissions.
Consistent icon-based voice selection overlay with automatic "Best" voice detection for target language pronunciation.
Append ?quiz=1 to the URL on components like tj-listening to hide transcripts and enable pure assessment mode.
Supply custom Google Apps Script URLs, remote data URLs, and teacher codes via attributes (submission-url, src, code) or URL search parameters across all components.
No central database or middleman server. Student submissions travel directly from the browser to the teacher's personal Google Sheet via Google Apps Script.
When embedding components (especially <tj-quiz-element>) inside Google Sites (🎬 Watch Video Tutorial ↗) (via Embed → Embed code) or WordPress (via Custom HTML block), follow these best practices:
type="module" & Remove defer: Ensure script tags use type="module" and omit defer inside iframe blocks so ES module scripts load synchronously within the iframe sandbox.<script type="text/markdown">: For <tj-quiz-element>, place quiz text inside a <script type="text/markdown"> tag to protect section dividers (---) and special characters (like &) from HTML sanitizers.<link> tag inside the embed code block so the isolated iframe renders typography correctly.<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;600;800&family=Inter:wght@400;600&display=swap" rel="stylesheet">
<script type="module" src="https://scripts.teacherjake.com/tj-quiz-element.js"></script>
<tj-quiz-element test-mode start-code="1234" teacher-code="7676" submission-url="YOUR_GAS_URL">
<script type="text/markdown">
B1 English Practice: Past Simple & Past Continuous
---instructions
Read the passage below and answer the questions.
---text
Last weekend, Sarah decided to take a trip to the mountains.
---questions-2
Q: Where did Sarah go?
A: To the mountains [correct]
A: To the beach
</script>
</tj-quiz-element>
Teachers can set up their own Google Sheet to automatically receive score submissions from any component (e.g., <tj-quiz-element>, <tj-grammar-hearts>, <tj-reader>, <tj-pronunciation>, etc.).
Use our pre-configured Google Sheet template with built-in Apps Script code and pre-formatted headers.
📊 Make a Copy of Spreadsheet Template ↗Alternatively, view the template before copying: Open Shared Google Sheet
Submissions tab and Apps Script are pre-installed.https://script.google.com/macros/s/.../exec) and paste it into TJ Builder or your component's submission-url attribute.Pass your Web App URL, remote JSON URL, or custom Submit Code via HTML attributes:
<tj-quiz-element submission-url="YOUR_GAS_URL" src="https://example.com/quiz.json" code="1234" teacher-code="7676"></tj-quiz-element>
If building a Google Sheet manually from scratch without using the template, ensure the default sheet tab is named exactly Submissions (capital S, plural, no spaces).
/** @OnlyCurrentDoc */
function doPost(e) {
try {
if (!e || !e.postData || !e.postData.contents) {
throw new Error("No data provided.");
}
const data = JSON.parse(e.postData.contents);
const sanitize = (input) => {
if (input === null || input === undefined) return "";
let str = String(input).substring(0, 2000).trim();
if (/^[=\+\-@]/.test(str)) {
str = "'" + str;
}
return str;
};
const cleanScore = Number(data.score) || 0;
const cleanTotal = Number(data.total) || 0;
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Submissions');
if (!sheet) {
throw new Error("Target sheet not found.");
}
if (sheet.getLastRow() === 0) {
sheet.appendRow([
'Timestamp', 'Nickname', 'Homeroom', 'Student ID',
'Quiz Name', 'Score', 'Total Questions', 'Written Answers'
]);
}
sheet.appendRow([
new Date(),
sanitize(data.nickname),
sanitize(data.homeroom),
sanitize(data.studentId),
sanitize(data.quizName),
cleanScore,
cleanTotal,
sanitize(data.writtenAnswers)
]);
return ContentService
.createTextOutput(JSON.stringify({
'result': 'success',
'message': 'Your score was submitted successfully!'
}))
.setMimeType(ContentService.MimeType.JSON);
} catch (error) {
console.error("Submission Error: ", error);
return ContentService
.createTextOutput(JSON.stringify({
'result': 'error',
'message': 'An error occurred while processing your submission.'
}))
.setMimeType(ContentService.MimeType.JSON);
}
}
TJ Components are built with a strict Zero-Data Retention & Privacy-First Philosophy. Unlike traditional educational software that requires centralized databases, user accounts, and third-party cloud servers, TJ Components run entirely client-side and connect directly to your own Google Account.
Our site never sees, intercepts, or stores student information. All student interactions (scores, nicknames, student numbers, written responses) are processed locally inside the student's web browser and transmitted directly to your personal or school Google Sheet via your Google Apps Script endpoint.
Student Browser ➔ Central Database & Server (Stores names, IDs, answers) ➔ Teacher Dashboard
Requires user sign-in, central database storage, third-party privacy liability, and subscription servers.
Student Browser ➔ Direct HTTPS POST ➔ Teacher's Google Sheet
CDN serves static JavaScript components only. Data flows directly into the teacher's private Google account.
Standardized HTML Custom Elements (Shadow DOM, ES Modules) run natively in any modern browser. Embed easily into Google Sites, WordPress, Canvas, Moodle, or static HTML without framework dependencies or build steps.
Provides a free, serverless backend that logs score submissions straight into Google Sheets—a familiar spreadsheet interface every educator knows, requiring zero database maintenance or API subscription fees.
<lbl-reader>)An interactive story reader with word highlighting, Text-to-Speech, and automatic matching activities. ✨ Generate with Gemini Gem ↗
<lbl-reader
lang-original="en"
lang-translation="th"
story-title="My Daily Routine">
[
{
"original": "I wake up at 7 AM every day.",
"fullTranslation": "ฉันตื่นนอนตอน 7 โมงเช้าทุกวัน",
"translationOptions": ["ตื่นนอน", "นอนหลับ", "แปรงฟัน"],
"correctTranslationIndex": 0,
"highlightIndex": 1
}
]
</lbl-reader>
<grammar-hearts>)A gamified grammar practice component with lives, multiple-choice, and sentence scrambling. ✨ Generate with Gemini Gem ↗
<grammar-hearts hearts="3" round-size="10">
{
"title": "Daily Routines Quiz",
"questions": [
{
"type": "multiple-choice",
"question": "She ___ (work) every day.",
"options": ["works", "is working"],
"correctIndex": 0
}
]
}
</grammar-hearts>
<tj-info-gap>)Collaborative multi-player activity for communication practice or single-player mode with TTS partner. ✨ Generate with Gemini Gem ↗
<tj-info-gap>
{
"topic": "Ordering Delivery",
"blocks": [
{
"text_holder_id": 1,
"text": "Wanchai wants pad thai.",
"questions": [
{ "asker_id": 2, "question": "What does he want?", "options": ["Pad Thai", "Rice"], "correct_answer": "Pad Thai" }
]
}
]
}
</tj-info-gap>
<tj-listening>)Comprehensive listening lesson with vocabulary preview, dialogue playback, and comprehension quiz. ✨ Generate with Gemini Gem ↗
<tj-listening audio-listening="url_to_mp3">
{
"title": "Ordering Food",
"lang": "en-US",
"vocab": [
{ "word": "bill", "definition": "Charges for food.", "example": "Bill please." }
],
"listening": {
"transcript": "Waiter: Hello...",
"questions": [
{ "question": "What did they order?", "options": ["Food", "Drink"], "correct": "Food" }
]
}
}
</tj-listening>
<tj-speed-review>)Fast-paced review activity with a countdown timer where students earn points based on how quickly they answer questions. ✨ Generate with Gemini Gem ↗
<tj-speed-review time-limit="15" round-size="3">
[
{
"title": "Suffix Speed Run: Noun Builder",
"questions": [
{
"category": "Verb → Noun",
"question": "The act of **defining** a word is its ____.",
"options": ["definition", "definement", "wisdom", "arrival"],
"answer": "definition",
"explanation": "To turn the verb **define** into a noun, we add the suffix **-tion**."
}
]
}
]
</tj-speed-review>
<tj-test>)Multi-stage level placement test powered by JSON configuration where students unlock subsequent levels by meeting target score cutoffs. ✨ Generate with Gemini Gem ↗
<tj-test test-mode start-code="1234" teacher-code="7676" pass-threshold="75%" submission-url="YOUR_GAS_URL">
<script type="application/json">
{
"title": "Comprehensive English Assessment",
"sections": [
{
"title": "Section 1: Vocabulary",
"vocabulary": [
{ "word": "Resilient", "def": "Able to withstand or recover quickly from difficult conditions." },
{ "word": "Innovate", "def": "Make changes in something established, especially by introducing new methods or ideas." },
{ "word": "Perspective", "def": "A particular attitude toward or way of regarding something; a point of view." }
]
},
{
"title": "Section 2: Grammar",
"questions": [
{
"situation": "Two colleagues are discussing their weekend plans.",
"question": "Alex: \"Have you finished the project report yet?\"\nTaylor: \"Not yet. If I ______________ more time yesterday, I would have completed it.\"",
"options": [
"had had",
"have had",
"would have",
"was having"
],
"answer": "had had",
"explanation": "Third conditional requires past perfect ('had had') in the if-clause."
},
{
"question": "Choose the correct sentence:",
"options": [
"Neither of the answers are correct.",
"Neither of the answers is correct.",
"Neither of the answers were correct.",
"Neither of the answers be correct."
],
"answer": "Neither of the answers is correct.",
"explanation": "'Neither' takes a singular verb ('is')."
}
]
},
{
"title": "Section 3: Reading Comprehension",
"passages": [
"Renewable energy sources such as solar and wind power are becoming increasingly vital in combating global climate change. Unlike fossil fuels, solar energy generates electricity without producing greenhouse gas emissions during operation. However, effective energy storage technologies, such as advanced lithium-ion batteries, are essential to ensure a stable supply when sunlight or wind is unavailable."
],
"questions": [
{
"question": "What is mentioned as a key benefit of solar energy compared to fossil fuels?",
"options": [
"It is less expensive to install.",
"It generates electricity without greenhouse gas emissions during operation.",
"It works continuously regardless of weather conditions.",
"It requires no battery storage."
],
"answer": "It generates electricity without greenhouse gas emissions during operation.",
"explanation": "The text states solar energy generates electricity without producing greenhouse gas emissions during operation."
},
{
"question": "Why are energy storage technologies essential for renewable energy?",
"options": [
"To reduce the cost of solar panels.",
"To maintain a stable power supply when sunlight or wind is unavailable.",
"To replace fossil fuels immediately.",
"To export energy to other countries."
],
"answer": "To maintain a stable power supply when sunlight or wind is unavailable.",
"explanation": "The passage notes batteries ensure a stable supply when sunlight or wind is unavailable."
}
]
},
{
"title": "Section 4: Cloze",
"cloze": [
{
"text": "Every *morning*, Alex wakes *up* early to prepare for work. He enjoys drinking *coffee* while reading the daily *news* before leaving the house."
}
]
},
{
"title": "Section 5: Short Answer",
"questions": [
{
"question": "Explain in 2-3 sentences why renewable energy adoption is important for the environment.",
"options": []
},
{
"question": "Describe a personal experience where you had to solve a difficult problem at school or work.",
"options": []
}
]
}
]
}
</script>
</tj-test>
Set a universal "passThreshold": "75%" at the root JSON level (or via pass-threshold="75%" attribute) to specify score cutoffs for section unlock.
Add test-mode attribute to lock behind start-code and track tab-switching.
Set default or section-specific target percentage to progress to higher levels.
<tj-chapter-book>)A multi-chapter reading companion with built-in TTS, translation toggles, and comprehension checks. ✨ Generate with Gemini Gem ↗
<tj-chapter-book>
{
"title": "My Adventure",
"chapters": [
{
"title": "Chapter 1",
"text": "Once upon a time...",
"translation": "กาลครั้งหนึ่ง...",
"quiz": [
{ "question": "Who was there?", "options": ["Hero", "Villain"], "answer": 0 }
]
}
]
}
</tj-chapter-book>
<tj-pronunciation>)Practice speaking with native audio comparison, minimal pair discrimination, and sentence scrambles. ✨ Generate with Gemini Gem ↗
<tj-pronunciation>
{
"title": "Unit 1: Basic Listening & Recording",
"instructions": "Listen carefully. For Minimal Pairs, choose the final word spoken.",
"language": "en-US",
"activities": [
{
"type": "listen_record",
"targetText": "The ship is leaving the port.",
"phoneticHint": "ðə ʃɪp ɪz ˈliːvɪŋ ðə pɔːt",
"translation": "เรือกำลังออกจากท่าเรือ"
},
{
"type": "minimal_pair",
"focus": "Vowel /ɪ/ vs /iː/",
"options": ["ship", "sheep"],
"correctAnswer": "ship"
}
]
}
</tj-pronunciation>
Practice speaking with recording and TTS comparison, IPA hints, and translations.
Discriminate between similar sound contrasts with instant audio feedback.
Rebuild spoken sentences by dragging words into order with distractors.
<tj-quiz-element>) Inactive / Legacy[Inactive / Legacy Component] Maintained for backwards compatibility of existing quizzes. For new placement tests and quizzes, use <tj-test>. ✨ Generate with Gemini Gem ↗
<tj-quiz-element test-mode start-code="1234" teacher-code="7676" submission-url="YOUR_GAS_URL">
<script type="text/markdown">
My Quiz Title
---text
This is a reading passage...
---instructions
Choose the best answer for each question.
---questions-3
Q: What happened?
A: Nothing
A: Everything [correct]
---vocab-5
Word: Definition
Concept: Explanation
---cloze-2
The [cat] sat on the [mat].
</script>
</tj-quiz-element>
Append -N to any section (e.g., ---questions-3) to randomly show N items.
Use ---instructions to add custom guidance between quiz sections.
Format as Word: Definition (one per line) for matching activities.
Add test-mode attribute to hide correctness feedback, score details, and the "Try Again" button to secure assessments.