PageSourceSearch

https://tutero.ai/

html tutero.ai collected 2026-10-05 13:58:25 UTC 10,114 bytes, 203 lines download raw bytes

1<!doctype html>
2<html lang="en-AU">
3  <head>
4    <meta charset="UTF-8" />
5    <!--
6      The document is served at any path, and the Flutter loader that embed.js
7      appends resolves main.dart.js and its assets against document.baseURI:
8      without this, a deep link at /lesson-plan/<id> would fetch them from
9      /lesson-plan/. The shell's own URLs are absolute under /_shell/.
10    -->
11    <base href="/" />
12    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
13    <!--
14      The marketing front door's purple (R158): the browser paints its own chrome
15      with this before a pixel of the page, so a blue bar over a purple hero is
16      the first thing a visitor sees get corrected. Tutoring's document keeps its
17      own; `src/documents.test.ts` holds the pair in step on everything else.
18    -->
19    <meta name="theme-color" content="#B300EE" />
20    <!-- The marker the smoke reads: this document is the shell's, not Flutter's. -->
21    <meta name="tutero-app" content="shell" />
22    <!--
23      A returning browser may still run the old Flutter page's COI service
24      worker (coi-serviceworker.js, scope /): it re-issues every request, and
25      a navigation re-issued that way reads as no document at the edge, so the
26      browser was handed the old page instead of this one (2026-09-06). Evict
27      every registration and, if this document came through one, load it again
28      clean — once: with nothing registered, the second load evicts nothing.
29    -->
30    
30<script>
31      if ('serviceWorker' in navigator) {
32        navigator.serviceWorker
33          .getRegistrations()
34          .then(function (registrations) {
35            return Promise.all(
36              registrations.map(function (registration) {
37                return registration.unregister();
38              }),
39            );
40          })
41          .then(function (gone) {
42            if (gone.some(Boolean) && navigator.serviceWorker.controller)
43              location.reload();
44          })
45          .catch(function () {});
46      }
47    </script>
47
48
49    <!--
50      The ad networks' bootstrap, the Flutter build's own file, from the origin
51      (`shell-analytics` design D2). Flutter's index.html loaded it and this
52      document replaced that page, so without this line the Meta pixel never
53      initialises, the landing's click ids and campaign are never captured, and
54      every `metaPixel*` global the hosted app calls after the reveal is
55      undefined - which that app's own guards turn into silence rather than an
56      error, so nothing anywhere said the conversions had stopped (the audit,
57      2026-09-16).
58
59      The file's own `META_TRACKED_HOSTS` gate is what keeps dev, staging,
60      preview and the rig from reporting; the capture into storage runs on every
61      host that loads it, and a signup on a later document reads it back.
62
63      `defer`, as Flutter's page has it: a module script is deferred too, so
64      document order still runs this first - before React mounts, and so before
65      the shell replaces the entry the visitor arrived by, which is the one
66      thing that would strip the query this file exists to read. Root-absolute
67      and the origin's, like every other asset in this head: it is not a
68      document, so the Worker forwards it to Flutter's nginx.
69
70      Tutoring's document does not carry it. The pixel, its id and the Mixpanel
71      tokens beside it are the SCHOOLS project's, and `src/documents.test.ts`
72      holds that difference.
73    -->
74    
74<script src="/ad_pixel.js" defer></script>
74
75
76    <!--
77      The public front door's head, ported from schools-app/web/index.html: this
78      document replaces Flutter's on every URL of tutero.ai, so the title, the
79      description, the canonical and the social card have to be here or they are
80      gone. The tutoring product's head is its own document, tutoring.html
81      beside this file, and the Worker picks by the row's product (tutoring-shell
82      design D2); src/documents.test.ts keeps the two in step. Every asset
83      below is root-relative and the Flutter origin's — /icons, /favicon.*,
84      /manifest.json are files, so the Worker forwards them there.
85    -->
86    <title>The AI Teaching Platform for Schools | Tutero AI</title>
87    
87<script>
88      // The <title> above stays descriptive for a crawler that reads raw HTML.
89      // People see this instead, from the first frame: Flutter sets "Tutero AI"
90      // once it boots (schools-app #4690), and its own index.html does the same
91      // pre-boot (#4749), but that page is never the document here — so without
92      // this the tab shows the long SEO title for the whole loading state.
93      document.title = 'Tutero AI';
94    </script>
94
95    <meta
96      name="title"
97      content="The AI Teaching Platform for Schools | Tutero AI"
98    />
99    <meta
100      name="description"
101      content="Curriculum-aligned resources for every subject, every year level, every student. Free for teachers. Built for schools."
102    />
103    <!-- One search surface: every host and route points at tutero.ai. -->
104    <link rel="canonical" href="https://tutero.ai/" />
105    <meta property="og:type" content="website" />
106    <meta property="og:site_name" content="Tutero AI" />
107    <meta property="og:locale" content="en_AU" />
108    <meta property="og:locale:alternate" content="en_US" />
109    <meta property="og:url" content="https://tutero.ai/" />
110    <meta
111      property="og:title"
112      content="The AI Teaching Platform for Schools | Tutero AI"
113    />
114    <meta
115      property="og:description"
116      content="Curriculum-aligned resources for every subject, every year level, every student. Free for teachers. Built for schools."
117    />
118    <!--
119      Root-relative on purpose, as Flutter's page had it: the card ships with the
120      Flutter build and resolves against whichever host serves the page; an
121      absolute tutero.ai URL 404s on every other host. og:url and canonical stay
122      absolute — those are identity, not per-host assets.
123    -->
124    <meta property="og:image" content="/icons/tutero_ai_card.png" />
125    <meta property="og:image:width" content="1200" />
126    <meta property="og:image:height" content="630" />
127    <meta
128      property="og:image:alt"
129      content="Tutero AI — The AI Teaching Platform for Schools"
130    />
131    <meta name="twitter:card" content="summary_large_image" />
132    <meta name="twitter:url" content="https://tutero.ai/" />
133    <meta
134      name="twitter:title"
135      content="The AI Teaching Platform for Schools | Tutero AI"
136    />
137    <meta
138      name="twitter:description"
139      content="Curriculum-aligned resources for every subject, every year level, every student. Free for teachers. Built for schools."
140    />
141    <meta name="twitter:image" content="/icons/tutero_ai_card.png" />
142
143    <meta name="apple-mobile-web-app-capable" content="yes" />
144    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
145    <meta name="apple-mobile-web-app-title" content="Tutero AI" />
146    <!--
147      Icons keep fixed paths on the Flutter origin, whose nginx caches them for
148      30 days, so an unversioned URL pins whatever face a browser saw first.
149      Flutter's postbuild.sh versions its own index.html, which is never the
150      document here. Bump v when the schools icons are redrawn (2026-09-03:
151      the gradient bulb, schools-app e4cc48ef9).
152    -->
153    <link
154      rel="apple-touch-icon"
155      sizes="180x180"
156      href="/icons/apple-touch-icon-180.png?v=20260903"
157    />
158    <link rel="icon" type="image/svg+xml" href="/favicon.svg?v=20260903" />
159    <link rel="icon" type="image/x-icon" href="/favicon.ico?v=20260903" />
160    <link
161      rel="icon"
162      type="image/png"
163      sizes="32x32"
164      href="/favicon-32.png?v=20260903"
165    />
166    <link rel="manifest" href="/manifest.json" />
167    
167<script type="application/ld+json">
168      {
169        "@context": "https://schema.org",
170        "@type": "WebSite",
171        "name": "Tutero AI",
172        "url": "https://tutero.ai/",
173        "description": "Curriculum-aligned resources for every subject, every year level, every student. Free for teachers. Built for schools.",
174        "publisher": {
175          "@type": "Organization",
176          "name": "Tutero",
177          "url": "https://tutero.ai/",
178          "logo": "https://tutero.ai/icons/Icon-512.png"
179        }
180      }
181    </script>
181
182    
182<script type="module" crossorigin src="/_shell/assets/jsx-runtime-B-hcVAMW.js"></script>
182
183    
183<script type="module" crossorigin src="/_shell/assets/react-dom-sF8Euvcq.js"></script>
183
184    
184<script type="module" crossorigin src="/_shell/assets/gateway-ddsAfzqb.js"></script>
184
185    
185<script type="module" crossorigin src="/_shell/assets/createLucideIcon-obE1SVnH.js"></script>
185
186    
186<script type="module" crossorigin src="/_shell/assets/hosts--siLJs60.js"></script>
186
187    
187<script type="module" crossorigin src="/_shell/assets/index.esm-BUF99XsV.js"></script>
187
188    
188<script type="module" crossorigin src="/_shell/assets/routes-B_nT1eGE.js"></script>
188
189    
189<script type="module" crossorigin src="/_shell/assets/graphql-BS9dRCSv.js"></script>
189
190    
190<script type="module" crossorigin src="/_shell/assets/ClientError-DAeenrJp.js"></script>
190
191    
191<script type="module" crossorigin src="/_shell/assets/glyphs-rCf5WIFi.js"></script>
191
192    
192<script type="module" crossorigin src="/_shell/assets/main-Dv6ObtyW.js"></script>
192
193    <link rel="stylesheet" crossorigin href="/_shell/assets/main-BI0iH-4l.css">
194    <link rel="preload" as="font" type="font/woff2" href="/_shell/assets/material-symbols-rounded.subset-vCmJCx2P.woff2" crossorigin="">
195    <link rel="preload" as="font" type="font/woff2" href="/_shell/assets/material-icons.subset-Iozlg0Ir.woff2" crossorigin="">
196    <link rel="preload" as="font" type="font/woff2" href="/_shell/assets/satoshi-900-Dz0lUPy3.woff2" crossorigin="">
197    <link rel="preload" as="font" type="font/woff2" href="/_shell/assets/satoshi-700-D1Ud6wMl.woff2" crossorigin="">
198    <link rel="preload" as="font" type="font/woff2" href="/_shell/assets/hanken-grotesk-400-cejaMU9T.woff2" crossorigin="">
199  </head>
200  <body>
201    <div id="root"></div>
202  </body>
203</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.