20260630T154638Z-477b
- Audited URL
- https://php85.gotoand.dev/larsen
- Timestamp
- 2026-06-30T15:48:32.210Z
- Kind
- single
- Pages
- 1
Weighted audit summary
PSI mobile 94 indicates excellent code performance, but the HTTP 401 status blocks public access, creating a critical functional failure. Security headers are completely missing (0/100), and accessibility has a serious contrast violation. The site appears to be a staging environment given the 401 challenge and dev subdomain, but for production readiness, these must be fixed.
Audit Report: Viga 401 - Error 401 | Veebimajutus.ee
Website: https://php85.gotoand.dev/larsen
Date: 2026-06-30
Overall Score: 45 / 100
Status: 🟠 Poor
Confidence: high
Audit Coverage: 100% — all sources returned data
Summary
PSI mobile 94 indicates excellent code performance, but the HTTP 401 status blocks public access, creating a critical functional failure. Security headers are completely missing (0/100), and accessibility has a serious contrast violation. The site appears to be a staging environment given the 401 challenge and dev subdomain, but for production readiness, these must be fixed.
PageSpeed Insights — Mobile vs Desktop
Lower is worse for Performance; higher is worse for LCP and CLS. Worse value is bolded.
| Strategy | Performance (M / D) | LCP (M / D) | CLS (M / D) |
|---|---|---|---|
| Mobile vs Desktop | 94 / 100 | 2.44 s / 683 ms | 0.002 / 0.000 |
Optimization Checklist
1 of 3 passing — 1 pass · 1 warn · 1 fail · 4 n/a
| Item | Status | Detail |
|---|---|---|
| Page caching plugin / CDN active | Fail | No WordPress cache plugin marker or CDN edge cache detected on the document response. |
| Images lazy-loaded | Pass | All raster images use loading="lazy". |
| Hero image eagerly loaded | Warn | Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP. |
| Hero is a real <img> (not a CSS background-image) | N/A | No CSS background-images detected on raster-image-eligible elements. |
| Responsive images (srcset / <picture>) | N/A | Only 1 raster image on the page — responsive-image rule does not apply. |
| Reasonable number of image sizes | N/A | Too few raster images to evaluate srcset width variety. |
| JS scripts not blocking in <head> | N/A | No external scripts on the page. |
Fixes
Priority 1: Critical
Immediate action — impacts user experience, search rankings, or site safety.
1A. Resolve HTTP 401 Unauthorized Status
- Impact: Site Accessibility, SEO
- Problem: The server returns a 401 status with Basic Auth challenge (www-authenticate: Basic), blocking public access and failing the PSI http-status-code audit.
- Solution:
If this is a public site, remove server-side authentication (Basic Auth) from the web server config (e.g.,
.htaccessor Nginx config). If it must remain private, ensure the URL is not indexed and provide a public landing page.
1B. Implement Baseline Security Headers
- Impact: Transport Security, Clickjacking, MIME Sniffing
- Problem: Security Headers score is 0/100; HSTS, X-Frame-Options, and X-Content-Type-Options are missing.
- Solution:
Add the following headers to the server response:
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff"
Priority 2: Important
Essential for compliance, user reach, and search visibility.
2A. Fix Accessibility Violations (Contrast & Landmarks)
- Impact: WCAG 1.4.3, 1.3.1, 2.4.1
- Problem: axe-core reports 1 serious color-contrast violation and missing main landmark; W3C shows 3 h1 elements.
- Solution:
- Increase contrast on
.navbar-navlinks to ≥4.5:1. - Wrap main content in
<main>and navigation in<nav>. - Consolidate to a single
<h1>per page.
- Increase contrast on
2B. Add Missing SEO Meta Tags
- Impact: Search Visibility, Indexing
- Problem: PSI SEO score 82; missing meta description, canonical URL, and robots.txt.
- Solution:
Add to
<head>:<meta name="description" content="..."> <link rel="canonical" href="https://php85.gotoand.dev/larsen">
Priority 3: Best Practice
Recommended for long-term maintainability.
3A. Validate HTML Structure
- Impact: Browser Compatibility, Maintainability
- Problem: W3C Validator reports 6 errors including invalid
actionon forms andstyleinbody. - Solution:
- Remove empty
actionattributes or set to.. - Move
<style>blocks to<head>. - Fix
srcon<source>elements to usesrcsetor remove invalid attributes.
- Remove empty
▸Raw Markdown sent to the LLM
# Audit — https://php85.gotoand.dev/larsen
Run: 2026-06-30T15:46:38.863Z
## Audit Coverage
**100%** of audit sources returned data.
_All sources OK._
## Methodology
Each tool below contributes data to a single overall 0–100 site quality score. Performance dominates the weighting (~40%), followed by accessibility (~30%), image assets (~15%), and SEO/security (~15%). These weights are informative — the score is judged holistically, not from a fixed formula.
Severity scale in `priorities[]`:
- **high** — blocking issue / vulnerability / fail.
- **medium** — significant degradation.
- **low** — minor improvement.
Each tool section below lists: scores → priority fixes → findings → manual checks the tool cannot verify.
## Site Signals (inferred)
Heuristic site-shape signals derived from the audit data. Use these to calibrate the priority of security-header recommendations (see system rubric). Override when the evidence is clearly wrong.
- Auth surface: no
- Payments: no
- User-generated content: no
- E-commerce: no
## PageSpeed Insights
_Captured in 11127 ms (mobile + desktop in parallel)._
**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **94** | 100 |
| Accessibility | 87 | 87 |
| Best Practices | **92** | 96 |
| SEO | 82 | 82 |
**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **2.4 s** | 0.7 s |
| CLS | **0.002** | 0.000 |
| TBT | 0 ms | 0 ms |
| FCP | **2.44 s** | 683 ms |
| Speed Index | **2.44 s** | 683 ms |
| TTFB | 5 ms | **6 ms** |
### Priority fixes
1. **first-contentful-paint** (medium) — 2.4 s
2. **document-latency-insight** (medium) — Est savings of 18 KiB
3. **network-dependency-tree-insight** (high)
4. **render-blocking-insight** (high) — Est savings of 1,530 ms
5. **unminified-css** (medium) — Est savings of 5 KiB
### Findings (mobile)
#### Layout-shift sources
- body > div.container > div.footer--inner — shift 0.002
#### DOM size
- Total nodes: 0
#### Failing modeled audits
- SEO: `metaDescription`
- SEO: `canonical`
- SEO: `robotsTxt`
- SEO: `tapTargets`
- SEO: `structuredData`
- Best Practices: `errorsInConsole`
#### All failing PSI audits (sorted by weight × failure margin)
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `first-contentful-paint` (performance, score 0.69, weight 10) — First Contentful Paint — 2.4 s
- `landmark-one-main` (accessibility, score 0.00, weight 3) — Document does not have a main landmark.
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `image-size-responsive` (best-practices, score 0.00, weight 1) — Serves images with low resolution
- `errors-in-console` (best-practices, score 0.00, weight 1) — Browser errors were logged to the console
- `meta-description` (seo, score 0.00, weight 1) — Document does not have a meta description
- `http-status-code` (seo, score 0.00, weight 1) — Page has unsuccessful HTTP status code — 401
### Manual checks
- Real-device behavior on slow 3G / low-tier mobile hardware (Lighthouse is throttled simulation).
- Sustained INP under typical user interaction, not just initial load.
- CrUX data interpretation if site is low-traffic and field data falls back to origin or is missing.
## Security Headers & HTTP
_Captured in 36 ms._
**Transport:**
- Final URL: https://php85.gotoand.dev/larsen
- Status: 401
- Redirected: false
- HTTPS redirect: HTTP → HTTPS ✓
**Caching:**
- cache-control: not set
- etag: "6d1f-64639215c562e"
- last-modified: Thu, 18 Dec 2025 12:30:47 GMT
- expires: n/a
- pragma: n/a
- vary: n/a
- Issues:
- no cache-control header — caching behavior is unpredictable
**Compression:**
- content-encoding: n/a
- content-length: 27935
- Decoded body: 27.3 KB
- Compression ratio: 1
- Issues:
- response not compressed (27935 bytes uncompressed)
### Priority fixes
1. **strict-transport-security missing** (high) — Add HSTS with max-age >= 1 year, includeSubDomains, and preload
2. **content-security-policy missing** (high) — Add a CSP with default-src and script-src restrictions
3. **x-frame-options missing** (medium) — Prefer CSP frame-ancestors; X-Frame-Options as fallback
4. **x-content-type-options missing** (medium) — Send X-Content-Type-Options: nosniff
5. **weak caching policy** (medium) — no cache-control header — caching behavior is unpredictable
6. **response not compressed** (medium) — response not compressed (27935 bytes uncompressed)
7. **referrer-policy missing** (low) — Set a Referrer-Policy such as strict-origin-when-cross-origin
8. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
9. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
10. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
### Findings
#### Tracked headers
- **strict-transport-security** (missing, high)
- **content-security-policy** (missing, high)
- **x-frame-options** (missing, medium)
- **x-content-type-options** (missing, medium)
- **referrer-policy** (missing, low)
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (missing, low)
#### Info disclosure
- Server: `Apache`
#### All response headers
```
accept-ranges: bytes
connection: Upgrade, Keep-Alive
content-length: 27935
content-type: text/html
date: Tue, 30 Jun 2026 15:46:38 GMT
etag: "6d1f-64639215c562e"
keep-alive: timeout=5, max=100
last-modified: Thu, 18 Dec 2025 12:30:47 GMT
server: Apache
upgrade: h2,h2c
www-authenticate: Basic realm="Larsen"
```
### Manual checks
- Cookie attributes set via JavaScript (not visible in HTTP response).
- CORS preflight behavior under non-GET methods (only GET response headers checked).
- HSTS preload list inclusion (check hstspreload.org).
- WAF / DDoS posture beyond what static headers reveal.
## W3C HTML Validator
_Captured in 2507 ms._
**Scoring:** 6 errors · 5 warnings · 9 cosmetic (suppressed)
### Priority fixes
1. **Bad value “” for attribute “action” on element “form”: Must be non-empty.** (medium) — x2, first at line 384
2. **Attribute “src” not allowed on element “source” at this point.** (medium) — x2, first at line 988
3. **Attribute “area-hidden” not allowed on element “form” at this point.** (medium) — x1, first at line 252
4. **Element “style” not allowed as child of element “body” in this context. (Suppressing further errors from this subtree.)** (medium) — x1, first at line 1360
### Issue groups
- (×1) [error] Attribute “area-hidden” not allowed on element “form” at this point. — first at line 252 `<form id="header-search" class="header__search-form" area-hidden="true" role="se`
- (×2) [error] Bad value “” for attribute “action” on element “form”: Must be non-empty. — first at line 384 `rch">
<form class="desktop-search-container js-desktop-search-container" act`
- (×2) [warning] To set the document’s location as the action for a form, omit the “action” attribute. — first at line 384 `rch">
<form class="desktop-search-container js-desktop-search-container" act`
- (×2) [warning] Section lacks heading. Consider using “h2”-“h6” elements to add identifying headings to all sections, or else use a “div” element instead for any cases where no heading is needed. — first at line 430 `<section
id="desktop-search-location-dropdown"
c`
- (×2) [error] Attribute “src” not allowed on element “source” at this point. — first at line 988 `<source
src="data:image/svg+xml,%3Csvg%2`
- (×1) [error] Element “style” not allowed as child of element “body” in this context. (Suppressing further errors from this subtree.) — first at line 1360 `pt>
<style>`
- (×1) [warning] This document appears to be written in Estonian but the “html” start tag has “lang="en"”. Consider using “lang="et"” (or variant) instead. — first at line 2 `TYPE html>
<html class="no-js" lang="en">
<head`
### Manual checks
- Whether each `<section>` / `<article>` wraps semantically meaningful content.
- Language tag accuracy for multi-language pages or quoted content.
- Whether structural choices align with the document outline algorithm in screen readers.
## axe-core (Accessibility)
_Captured in 1452 ms._
**Scoring:** 3 violations · 16 passes · critical 0 · serious 1 · moderate 2 · minor 0
### Priority fixes
1. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
2. **landmark-one-main** (medium) — Document should have one main landmark
3. **region** (medium) — All page content should be contained by landmarks
### Findings
#### `color-contrast` (serious) — WCAG: wcag2aa, wcag143
[Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright)
- `.navbar-nav > a[href$="veebimajutus.ee/"]`
- `.link--row:nth-child(2) > div:nth-child(1) > a`
- `.link--row:nth-child(2) > div:nth-child(2) > a`
- `.link--row:nth-child(2) > div:nth-child(3) > a`
- `.link--row:nth-child(3) > div:nth-child(1) > a`
- … and 2 more nodes
#### `landmark-one-main` (moderate)
[Document should have one main landmark](https://dequeuniversity.com/rules/axe/4.11/landmark-one-main?application=playwright)
- `html`
#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.navbar`
- `.container`
### Incomplete (axe could not determine)
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 4 nodes
### Manual checks
- Keyboard-only navigation flow + visible focus indicators on every interactive element.
- Screen reader output (NVDA, VoiceOver) for actual auditory experience.
- Modal focus trapping and restoration on close.
- Touch target sizes (44×44 px minimum per WCAG 2.5.8).
- Color contrast for elements with alpha-transparency or gradients (axe skips these).
## Browser Runtime
_Captured in 1457 ms._
**Capture summary:** 1 console events · 0 mixed-content requests · 4 network requests · 48.0 KB total
**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| document | 1 | 27.3 KB |
| font | 1 | 20.7 KB |
| stylesheet | 1 | 0 B |
| xhr | 1 | 0 B |
**Third-party origins (by bytes):**
- https://fonts.gstatic.com — 1 request, 20.7 KB
- https://fonts.googleapis.com — 2 requests, 0 B
**Slowest requests (top 5):**
- https://fonts.googleapis.com/css?family=Droid+Sans:400,700 (xhr) — 152 ms, 0 B
- https://fonts.googleapis.com/css?family=Droid+Sans:400,700 (stylesheet) — 139 ms, 0 B
- https://fonts.gstatic.com/s/droidsans/v19/SlGVmQWMvZQIdix7AFxXkHNSbQ.woff2 (font) — 125 ms, 20.7 KB
- https://php85.gotoand.dev/larsen (document) — 20 ms, 27.3 KB
### Priority fixes
1. **console error** (medium) — Failed to load resource: the server responded with a status of 401 ()
### Findings
#### Console events
- [error] Failed to load resource: the server responded with a status of 401 () (https://php85.gotoand.dev/larsen)
### Manual checks
- Console output during user interaction (load-only capture).
- Behavior on slow networks and constrained devices.
- WebGL / canvas FPS profiling via DevTools Layers panel.
- Service worker / cache behavior on repeat visits.
## HTML Inventory
_Captured in 1457 ms._
**Document:**
- Lang: en
- Title: Viga 401 - Error 401 | Veebimajutus.ee
- Canonical: not set
- Viewport: width=device-width, initial-scale=1
- Charset: UTF-8
- HTML bytes: 29605
**Meta tags:**
- Description: not set
- Robots: not set
- Theme color: not set
- Open Graph tags: 0 (none)
- Twitter tags: 0
- hreflang: none
- JSON-LD: none
**Heading outline:**
- Counts: h1 ×3, h2 ×0, h3 ×0, h4 ×0, h5 ×0, h6 ×0
- Sequence (first 20):
- h1: Viga 401
- h1: Error 401
- h1: Vaata lisaks
**Landmarks:**
- nav: **missing**
- main: **missing**
- header: **missing**
- footer: **missing**
- Skip-to-content link: **missing**
**Scripts:** 1 total — 0 defer, 0 async, 0 render-blocking. Speculation rules: no.
**Stylesheets:** 1 external, 1 inline (16.8 KB)
**Images:** 1 total — **0 without alt**, **1 without width/height**, 1 without loading="lazy"
Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| kpBQBYmiJCRUQaIoCQlVkChKQkIV/D+cxxFa72wHXQAAAABJRU5ErkJggg== | Veebimajutus | _n/a_ | _n/a_ | ✗ |
**Links:** 11 anchors — 11 external, 0 preconnect, 0 preload.
Vague repeated link text:
- "abi@veebimajutus.ee" ×2
### Priority fixes
1. **Document has 3 <h1> elements** (medium) — A page should have exactly one h1; multiple h1s break document outline
2. **Missing <nav> landmark** (medium) — No <nav> element found in document
3. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
4. **1 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)
### Manual checks
- Visual rendering of detected mojibake (browser may auto-correct for display).
- Whether decorative images correctly use empty `alt=""` (vs. content images missing it).
- Whether headings reflect actual document hierarchy semantically.
- Whether vague link text is disambiguated by `aria-label` or surrounding context.
## Optimized-Web Checklist
_Captured in 0 ms._
**Summary:** 1 pass · 1 warn · 1 fail · 4 n/a
**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✗ fail | No WordPress cache plugin marker or CDN edge cache detected on the document response. |
| Images lazy-loaded | ✓ pass | All raster images use loading="lazy". |
| Hero image eagerly loaded | ! warn | Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP. |
| Hero is a real <img> (not a CSS background-image) | – n/a | No CSS background-images detected on raster-image-eligible elements. |
| Responsive images (srcset / <picture>) | – n/a | Only 1 raster image on the page — responsive-image rule does not apply. |
| Reasonable number of image sizes | – n/a | Too few raster images to evaluate srcset width variety. |
| JS scripts not blocking in <head> | – n/a | No external scripts on the page. |
**Evidence:**
- Hero image eagerly loaded:
- `hero: …iKAkJVZAoSkJCFSSKkpBQBYmiJCRUQaIoCQlVkChKQkIV/D+cxxFa72wHXQAAAABJRU5ErkJggg==`
- `loading: (not set)`
- `fetchpriority: (not set)`
### Priority fixes
1. **Page caching plugin / CDN active** (high) — No WordPress cache plugin marker or CDN edge cache detected on the document response.
2. **Hero image eagerly loaded** (medium) — Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP.
### Manual checks
- Cart / checkout / logged-in pages must bypass the page cache or load dynamic regions via AJAX.
- Verify the cache is warmed for the canonical URL on initial deploy (first visitor should not pay the cold-start cost).
- Inspect "hero" image visually — heuristic above picks the first/largest <img>, which may not match the actual LCP element on JS-heavy pages.
- Confirm scripts marked as defer/async actually tolerate deferred execution (some legacy snippets break when reordered).