Produced against codebase at kigumo-TVC/ · Domain: kigumotvc.ac.ke · Hosting: cPanel / Passenger (Node.js)
| File | Status | Detail |
|---|---|---|
public/robots.txt | MISSING | No file existed. No crawl guidance, no Sitemap pointer. |
public/sitemap.xml | MISSING | No static or dynamic sitemap anywhere in the codebase. |
| Page | title | description | canonical | OG tags | viewport |
|---|---|---|---|---|---|
| index.html | ✓ | Weak — wrong county (Kirinyaga vs Murang'a) | ✗ | ✗ | ✓ |
| about.html | ✓ | ✓ | ✗ | ✗ | ✓ |
| courses.html | ✓ | ✓ | ✗ | ✗ | ✓ |
| departments.html | ✓ | Too short / generic | ✗ | ✗ | ✓ |
| news.html | ✓ | ✓ | ✗ | ✗ | ✓ |
| admissions.html | ✓ | ✓ | ✗ | ✗ | ✓ |
| contact.html | ✓ | ✓ | ✗ | ✗ | ✓ |
| downloads.html | ✓ | ✓ | ✗ | ✗ | ✓ |
| portals.html | ✓ | Vague — "and more" | ✗ | ✗ | ✓ |
| apply.html | ✓ | ✓ | ✗ | ✗ | ✓ |
| course-details.html | Generic | Generic "Course details" | ✗ | ✗ | ✓ |
| news-article.html | Generic | Generic "News Article" | ✗ | ✗ | ✓ |
Both pages use static HTML + client-side fetch — there is no server-side rendering. The HTML file is served with a generic title/description. Google's crawler does execute JavaScript, but the delay before JS runs means:
course-details.html?id=5 and course-details.html?id=12 both initially present the same <title> and <meta description> to the crawler.news-article.html — every article shared one generic title.news-article.html already updated document.title via JS (good partial fix), but did nothing with description, canonical, OG, or JSON-LD.course-details.html did nothing — not even document.title.Present — assets/images/logo.jpeg used as <link rel="icon"> on all pages. Not an ICO or PNG but JPEG is accepted by all modern browsers.
Correct on all pages audited. Each page has exactly one visible <h1> in the body (injected via JS on dynamic pages once data loads). No skipped heading levels observed.
Mostly good — static images in index.html and about.html have descriptive alt text (e.g. "Kigumo TVC Logo", "Kenya Government Coat of Arms"). Dynamic images (news cards, department images, staff photos) correctly use the item's real name as alt text via escapeHtml(article.title), escapeHtml(dept.name), etc. No alt="" or missing alt attributes found on content images.
Unresolved in code — The domain is kigumotvc.ac.ke (non-www, from docs). HTTPS is present (cPanel + SSL). However server/index.js had no redirect logic: a crawler reaching www.kigumotvc.ac.ke would get duplicate content. HTTP→HTTPS redirect is handled by cPanel/Apache at the webserver level (not visible in Node.js code), so it is assumed correct but cannot be verified from the codebase alone.
None — No schema.org markup existed anywhere on the site.
Bug — course-details.html loaded assets/js/navbar.js twice, which caused buildNavbar() to be called twice and the navbar to be rendered twice in the DOM.
| File | What changed & why |
|---|---|
public/robots.txt CREATED |
New file. Allows all public pages. Disallows /portal/, /innovation/admin/, /innovation/coordinator/, /api/, /uploads/. Points to /sitemap.xml. |
server/index.js EDITED |
(1) Sitemap route — GET /sitemap.xml added. Queries the live database for courses WHERE is_active=TRUE, all departments, and news_articles WHERE is_published=TRUE. Merges with 10 static pages. Returns valid XML with lastmod, changefreq, and priority. Non-fatal try/catch per DB query so static pages always serve even if DB is down. 1-hour cache header.(2) www→non-www redirect — Middleware added at the very top (before CORS). Sends 301 redirect from www.kigumotvc.ac.ke to kigumotvc.ac.ke in production only.
|
public/index.html EDITED |
Fixed description (wrong county corrected to Murang'a). Added canonical, all OG tags, and EducationalOrganization JSON-LD schema with real address, phone, email, and Facebook URL from the site's footer. |
public/about.html EDITED |
Improved description. Added canonical and OG tags. |
public/courses.html EDITED |
Improved title and description to name the actual departments. Added canonical and OG tags. |
public/departments.html EDITED |
Improved description to list actual department names. Added canonical and OG tags. |
public/news.html EDITED |
Improved description. Added canonical and OG tags. |
public/admissions.html EDITED |
Improved description. Added canonical and OG tags. |
public/contact.html EDITED |
Improved description with real phone number and email from the site footer. Added canonical and OG tags. |
public/downloads.html EDITED |
Improved description. Added canonical and OG tags. |
public/portals.html EDITED |
Improved description to name actual portal types. Added canonical and OG tags. |
public/apply.html EDITED |
Improved description. Added canonical and OG tags. |
public/course-details.html EDITED |
Dynamic SEO injection: once loadCourseDetails() receives the course from /api/v1/courses/:id, it writes a unique document.title, <meta description>, <link rel="canonical">, all OG meta tags, and a Course JSON-LD block — each using the real course name, description, level, and department from the API response.Default canonical set to /courses.html in HTML so pages without a valid ?id don't get indexed with a useless generic title.Duplicate navbar.js script removed. |
public/news-article.html EDITED |
Dynamic SEO injection: once loadArticle() receives the article, it writes a unique title, description (stripped from article body HTML, first 155 chars), canonical URL, all OG tags (including the article's own image if present, else fallback to logo), and a NewsArticle JSON-LD block with real datePublished.Default canonical set to /news.html in HTML for the same fallback reason.
|
www. → non-www (matching the docs which consistently use kigumotvc.ac.ke). If cPanel is actually configured the other way (non-www → www), the redirect in Node.js will fight it and cause redirect loops. Verify your cPanel "Redirects" or .htaccess settings and confirm which is the canonical version you want. If you prefer www, swap the redirect direction and update all canonical URLs in the HTML files.
| Item | Why it needs manual action |
|---|---|
| Google Search Console domain verification | You must add the site to Google Search Console, verify domain ownership (DNS TXT record via your registrar, or HTML file upload via cPanel), then submit https://kigumotvc.ac.ke/sitemap.xml under Indexing → Sitemaps. |
| HTTP → HTTPS redirect | This must be enforced at the Apache/cPanel level (via .htaccess or cPanel's "Force HTTPS" toggle). Node.js cannot enforce it because the TLS termination happens at Apache before requests reach the Node app. Verify it is already on. |
| Favicon format | The favicon is a JPEG (logo.jpeg). Modern browsers accept this, but for maximum compatibility (especially older Android and Windows) consider converting to a PNG or ICO and adding a 180×180 Apple Touch icon. No change was made as it works today. |
admissions@kigumotvc.ac.ke |
Found in admissions.html source. This email does not appear in the official contact information (only kigumotvc@gmail.com is in the footer). Verify whether this address is active before it gets indexed. |
| Google Analytics / Search Console integration | No analytics tag was found in the codebase. You cannot measure organic search traffic without it. Add a GA4 snippet or a Google Tag Manager container to assets/js/main.js or directly to each HTML <head>. |
| Crawler JS rendering for course/news pages | Google will see the injected title and meta on its second crawl pass (after JS executes). Bing and other crawlers may not execute JS and will only see the fallback static title. There is no way to fix this without SSR or a prerendering proxy. |
| Social share image dimensions | The og:image points to assets/images/logo.jpeg. Facebook and LinkedIn recommend 1200×630px. The current logo JPEG's actual dimensions were not checked. If it is small (e.g. a square logo), social share cards will look poor. Consider uploading a proper banner image and updating the og:image URL. |
<meta name="viewport"> — no action needed.<h1> per page — heading structure was already correct.index.html ("Kigumo TVC Logo", "Kenya Government Coat of Arms") already had descriptive alt text./innovation/ public pages (about.html, results.html) are not linked from the main site nav and do not need indexing — they are correctly accessible but not submitted via sitemap.