Inspiration

It started with a simple observation: professors assign discussion posts because they want to know if students are actually thinking about the material. But the more students engage, the more posts pile up and reading 30 individual responses line by line, trying to mentally track who understood elaborative encoding vs. who confused it with maintenance rehearsal, is exhausting work that scales poorly. We asked ourselves: what if a professor could get the insight without the reading time? What if AI could do the first pass not to replace the professor's judgment, but to make it faster and sharper? That question became CanvasInsight.

What it does

CanvasInsight is a Chrome extension for professors that uses AI to analyze Canvas discussion posts. Instead of a professor manually reading 30+ student responses, the extension:

Reads all the student posts from a Canvas discussion automatically Sends them to Claude AI along with course materials like lecture notes and the syllabus Generates a full report showing:

Overall class comprehension score Which topics students understood vs. struggled with A score and assessment for every individual student Which students need intervention, follow-up, or monitoring Action items for the professor Suggested follow-up discussion questions

The whole thing takes about 15 seconds instead of hours of manual reading. One sentence version: CanvasInsight turns a Canvas discussion full of student posts into an instant AI-powered comprehension report for the professor.

How we built it

CanvasInsight is a Chrome extension built entirely in vanilla JavaScript with no backend server. Every piece of intelligence runs directly in the browser. Architecture The project is 7 files: FileRolemanifest.jsonDeclares permissions, URL matches, and extension structurecontent.jsThe engine scrapes posts, calls Canvas API, calls Claude AIbackground.jsService worker saves history, manages storagepopup.html/jsThe toolbar popup with Analyze, History, and Settings tabsdashboard.html/jsThe full page professor report rendered after analysis The Data Pipeline When a professor clicks Analyze, the following happens:

Post collection - We first attempt to scrape the Canvas DOM using 7 different selector strategies for both the old and new React-based Canvas UI. If the DOM yields nothing (which happens when Canvas lazy-loads its React components), we fall back directly to the Canvas REST API:

GET /api/v1/courses/{id}/discussion_topics/{id}/entries\texttt{GET /api/v1/courses/{id}/discussion_topics/{id}/entries}GET /api/v1/courses/{id}/discussion_topics/{id}/entries This uses the professor's existing session cookie - no OAuth, no extra login.

Material collection - In parallel, we fetch the course syllabus, all Canvas lecture pages from modules, and any files the professor selected. Text content is capped per-source to keep the prompt manageable:

Total context=∑i=1nposti⏟student responses+syllabus1500+∑jpagej,2500+∑kfilek,3000⏟course materials\text{Total context} = \underbrace{\sum_{i=1}^{n} \text{post}i}{\text{student responses}} + \underbrace{\text{syllabus}{1500} + \sum{j} \text{page}{j,2500} + \sum{k} \text{file}{k,3000}}{\text{course materials}}Total context=student responsesi=1∑n​posti​​​+course materialssyllabus1500​+j∑​pagej,2500​+k∑​filek,3000​​​

AI analysis - We send a single structured prompt to claude-sonnet-4-20250514 with max_tokens: 8000, asking Claude to return a strict JSON schema including per-student comprehension scores, topic-level gap analysis, intervention recommendations, and follow-up questions. Rendering - Results are saved to chrome.storage.local and the dashboard opens in a new tab, reading from storage and rendering the full report.

Challenges we ran into

  1. The DOM Scraping Problem Canvas's frontend is a React single-page app. Posts are injected into the DOM asynchronously after page load, and the component structure changes between Canvas versions. Our original scraper worked on the old Canvas UI (discussion_entries, .discussion_entry) but failed completely on the modern one. We ended up implementing 7 cascading DOM strategies before falling back to the REST API, which became the true reliable foundation.
  2. Content Security Policy Violations When we first loaded the dashboard, the browser threw: Refused to execute inline script because it violates Content Security Policy Chrome MV3 disallows any inline JavaScript in extension pages including dynamically injected onclick handlers in innerHTML strings. Every event handler had to be converted to event delegation using data attributes. This required a full audit of the dashboard rendering code.
  3. No Backend - Browser-Only Constraints We deliberately chose to build without a backend to keep the project self-contained and easy to install. The tradeoff: we can't parse PDFs or DOCX files in the browser without a library, we can't sync history across devices, and we're constrained by chrome.storage.local's 5MB limit. For the hackathon scope these were acceptable but a production version would need a backend.
  4. Coordinating Two People on One Repo With a single JavaScript codebase and no clear frontend/backend boundary, merge conflicts were frequent. We learned to communicate which file each person was working on before committing, and used GitHub for version control throughout.

Accomplishments that we're proud of

Getting the Canvas API fallback working. The moment we realized DOM scraping wasn't reliable on Canvas's React UI was a real low point our demo was showing "0 students analyzed." Figuring out that we could bypass the DOM entirely and hit the Canvas REST API directly, using the professor's existing session cookie, was a genuine breakthrough. It made the extension actually work in the real world. Building a complete, installable product in one hackathon. This isn't a prototype that only runs locally with a bunch of setup steps. Any professor can download 7 files, load them into Chrome, paste an API key, and be analyzing discussions in under 2 minutes. That level of polish in a hackathon timeframe is something we're genuinely proud of. Solving the CSP violation without a framework. Debugging Chrome's Content Security Policy errors extracting inline scripts, converting onclick attributes to event delegation, tracking down every single inline handler in dynamically generated HTML was tedious, unglamorous work. Getting through it without reaching for a framework that would handle it for us felt like a real win. The dashboard. Opening that report for the first time and seeing real student names, real comprehension scores, and real intervention flags pulled from an actual Canvas discussion that was the moment the project felt real.

What we learned

-Chrome Manifest V3 is strict. Inline tags inside extension HTML pages are blocked by the Content Security Policy. We had to extract all JavaScript to external files and replace every onclick attribute with addEventListener. This took longer than expected. -Canvas&#39;s React UI doesn&#39;t render posts immediately. The modern Canvas interface lazy-loads discussion entries, meaning DOM scraping often returns zero results even when posts exist. The Canvas REST API is the reliable solution but we only discovered this when our demo showed &quot;0 students analyzed.&quot; -Token limits matter at scale. Our first version used max_tokens: 4000. For a class with 25+ students and course materials included, Claude&#39;s JSON response was getting truncated mid-object, causing Unexpected end of JSON input errors. Increasing to 8000 resolved it. -Prompt engineering for structured output is an art. Getting Claude to return clean, parseable JSON every time required being very explicit: specifying exact field names, types, and example values and ending the prompt with &quot;Return ONLY valid JSON, no markdown, no extra text.&quot; Stripping accidental markdown fences before JSON.parse() was also necessary.</p> <h2 id="whats-next-for-canvas-insight">What&#39;s next for Canvas Insight</h2> <p>PDF and DOCX support. Right now we can only read text-based files in the browser. Adding a lightweight backend with a PDF parser would let professors include their actual lecture slides and readings in the analysis making Claude&#39;s assessment significantly more accurate. Gradebook integration. Canvas has an API for grades too. We could pre-populate participation scores directly from the comprehension analysis, saving professors another manual step. Semester-wide trend analysis. Right now each discussion is analyzed in isolation. With a backend database, we could track individual students across every discussion in a semester spotting students whose comprehension is declining before it shows up in their exam grades. Institutional deployment. Instead of professors managing their own API keys, universities could deploy <strong>CanvasInsight</strong> as an approved integration with a shared API budget, full FERPA compliance review, and admin dashboards for department-level insights. Support for other LMS platforms. Blackboard, Moodle, and Google Classroom all have discussion features and APIs. The core architecture scrape posts, send to AI, render report works for any of them.</p>

Built With

  • analysis-results
  • and-syllabus-storage-chrome-storage-api-(chrome.storage.local)-?-api-key
  • api
  • course-files
  • css3
  • github
  • html5
  • javascript
  • modules
  • pages
Share this project:

Updates