orchard
mirrorEvery site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.
blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics
1{{- /* The Markdown report. Rendered by text/template, not html/template, so a
2 "*" stays a "*" instead of becoming an entity. See report.go.
3
4 The whitespace control markers ({{- and -}}) are doing real work here in
5 a way they are not in the HTML templates: Markdown is whitespace
6 sensitive, and an {{if}} on its own line would otherwise leave a blank
7 line that splits a list in two. */ -}}
8{{- with .Property -}}
9# {{ .Name }}
10
11`{{ .URL }}`
12
13## Snapshot
14
15- Current status: **{{ .CurrentStatus }}**
16- Average response: **{{ .AvgResponseTime }} ms**
17- Recent uptime: {{ if .RecentUptimePct }}**{{ pct1 .RecentUptimePct }}%**{{ else }}n/a{{ end }}
18- Total checks logged: **{{ .TotalChecks }}**
19
20## Lighthouse
21
22{{ with .LighthouseScores -}}
23{{ range .Pairs }}- {{ .Label }}: **{{ .Score }}**
24{{ end }}
25{{- else -}}
26_No lighthouse data._
27{{ end }}
28## Security headers
29
30| Header | State |
31|---|---|
32| HTTPS | {{ if .IsHTTPS }}yes{{ else }}no{{ end }} |
33| HSTS (1y+) | {{ if .HasHSTS }}yes{{ else }}no{{ end }} |
34| HSTS preload | {{ if .HasHSTSPreload }}yes{{ else }}no{{ end }} |
35| X-Frame-Options | {{ if .HasClickjackProtection }}set{{ else }}missing{{ end }} |
36| X-Content-Type-Options | {{ if .HasContentSniffProtection }}nosniff{{ else }}missing{{ end }} |
37| Server header hidden | {{ if .HidesServerVersion }}yes{{ else }}no{{ end }} |
38
39## SEO insights
40
41{{ if .CrawlerInsights -}}
42{{ range .CrawlerInsights }}- [{{ .Severity }}] [{{ .Type }}] {{ .Issue }}: `{{ .URL }}`
43{{ end }}
44{{- else -}}
45_No crawl results yet._
46{{ end }}
47{{- end }}