Audit

20260630T154638Z-477b

← Back to php85gotoanddev
Audited URL
https://php85.gotoand.dev/larsen
Timestamp
2026-06-30T15:48:32.210Z
Kind
single
Pages
1
Audit summary
https://php85.gotoand.dev/larsen
Pagespeed scores
Other checks
LLM Report

Weighted audit summary

45
Overall site quality
Poorhigh confidence

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., .htaccess or 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-nav links to ≥4.5:1.
    • Wrap main content in <main> and navigation in <nav>.
    • Consolidate to a single <h1> per page.

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 action on forms and style in body.
  • Solution:
    • Remove empty action attributes or set to ..
    • Move <style> blocks to <head>.
    • Fix src on <source> elements to use srcset or remove invalid attributes.
▸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).