---
tool: Crawlinx SEO audit
source: https://crawlinx.com
domain: kaelith.tw
report_url: "https://crawlinx.com/audit/kaelith.tw"
crawl_id: 20260720T114531-b9021bf1
health_score: 67
generated_at: 2026-08-26T02:37:24Z
total_pages: 45
html_pages: 43
indexable_pages: 43
errors: 0
warnings: 108
notices: 85
---

# SEO audit: kaelith.tw

**Health score: 67/100** — needs attention

> Audited by [Crawlinx](https://crawlinx.com) — the free technical-SEO crawler. Full report: https://crawlinx.com/audit/kaelith.tw

## Overview

| Metric | Value |
| --- | --- |
| Pages crawled | 45 |
| HTML pages | 43 |
| Indexable | 43 |
| Non-indexable | 0 |
| Orphan pages | 0 |
| Broken internal links | 0 |
| Avg response time | 1057 ms |
| Errors / Warnings / Notices | 0 / 108 / 85 |
| Status codes | 45×200 |

## Categories

| Category | Score | Errors | Warnings | Notices |
| --- | ---: | ---: | ---: | ---: |
| Security | 71 | 0 | 43 | 0 |
| Content | 74 | 0 | 39 | 0 |
| Meta Description | 83 | 0 | 25 | 17 |
| Video | 99 | 0 | 1 | 0 |
| Performance | 100 | 0 | 0 | 43 |
| Social | 100 | 0 | 0 | 25 |

## Issues

### Warnings (108)

#### Thin content (low word count)

- Rule: `content.thin` · Category: Content · Occurrences: 39

- [https://kaelith.tw/](https://kaelith.tw/) — 114 words
- [https://kaelith.tw/about](https://kaelith.tw/about) — 55 words
- [https://kaelith.tw/articles/2fa-recovery-codes](https://kaelith.tw/articles/2fa-recovery-codes) — 144 words
- [https://kaelith.tw/articles/access-control-idor](https://kaelith.tw/articles/access-control-idor) — 149 words
- [https://kaelith.tw/articles/account-compromise-response](https://kaelith.tw/articles/account-compromise-response) — 176 words
- [https://kaelith.tw/articles/app-permission-safety](https://kaelith.tw/articles/app-permission-safety) — 184 words
- [https://kaelith.tw/articles/browser-extension-safety](https://kaelith.tw/articles/browser-extension-safety) — 174 words
- [https://kaelith.tw/articles/cloud-sharing-privacy](https://kaelith.tw/articles/cloud-sharing-privacy) — 173 words
- [https://kaelith.tw/articles/content-security-policy](https://kaelith.tw/articles/content-security-policy) — 145 words
- [https://kaelith.tw/articles/csrf-protection](https://kaelith.tw/articles/csrf-protection) — 145 words
- [https://kaelith.tw/articles/data-breach-response](https://kaelith.tw/articles/data-breach-response) — 174 words
- [https://kaelith.tw/articles/dns-basics](https://kaelith.tw/articles/dns-basics) — 144 words
- [https://kaelith.tw/articles/domain-dns-takeover](https://kaelith.tw/articles/domain-dns-takeover) — 152 words
- [https://kaelith.tw/articles/online-shopping-security](https://kaelith.tw/articles/online-shopping-security) — 173 words
- [https://kaelith.tw/articles/password-manager](https://kaelith.tw/articles/password-manager) — 143 words
- [https://kaelith.tw/articles/phishing](https://kaelith.tw/articles/phishing) — 142 words
- [https://kaelith.tw/articles/public-wifi](https://kaelith.tw/articles/public-wifi) — 145 words
- [https://kaelith.tw/articles/responsible-vulnerability-disclosure](https://kaelith.tw/articles/responsible-vulnerability-disclosure) — 175 words
- [https://kaelith.tw/articles/scam-message-safety](https://kaelith.tw/articles/scam-message-safety) — 185 words
- [https://kaelith.tw/articles/secure-file-upload](https://kaelith.tw/articles/secure-file-upload) — 148 words
- [https://kaelith.tw/articles/security-incident-reporting](https://kaelith.tw/articles/security-incident-reporting) — 142 words
- [https://kaelith.tw/articles/security-logging-monitoring](https://kaelith.tw/articles/security-logging-monitoring) — 144 words
- [https://kaelith.tw/articles/self-xss](https://kaelith.tw/articles/self-xss) — 145 words
- [https://kaelith.tw/articles/service-worker-cache-security](https://kaelith.tw/articles/service-worker-cache-security) — 146 words
- [https://kaelith.tw/articles/session-cookie-security](https://kaelith.tw/articles/session-cookie-security) — 144 words
- [https://kaelith.tw/articles/social-engineering](https://kaelith.tw/articles/social-engineering) — 142 words
- [https://kaelith.tw/articles/software-supply-chain](https://kaelith.tw/articles/software-supply-chain) — 150 words
- [https://kaelith.tw/articles/ssl-certificate](https://kaelith.tw/articles/ssl-certificate) — 144 words
- [https://kaelith.tw/articles/two-factor-authentication](https://kaelith.tw/articles/two-factor-authentication) — 143 words
- [https://kaelith.tw/articles/website-backup](https://kaelith.tw/articles/website-backup) — 143 words
- [https://kaelith.tw/articles/website-maintenance-checklist](https://kaelith.tw/articles/website-maintenance-checklist) — 141 words
- [https://kaelith.tw/articles/website-malware](https://kaelith.tw/articles/website-malware) — 141 words
- [https://kaelith.tw/changelog](https://kaelith.tw/changelog) — 53 words
- [https://kaelith.tw/contact](https://kaelith.tw/contact) — 47 words
- [https://kaelith.tw/principles](https://kaelith.tw/principles) — 45 words
- [https://kaelith.tw/privacy](https://kaelith.tw/privacy) — 54 words
- [https://kaelith.tw/security](https://kaelith.tw/security) — 64 words
- [https://kaelith.tw/services](https://kaelith.tw/services) — 46 words
- [https://kaelith.tw/status](https://kaelith.tw/status) — 50 words

#### Content-Type header doesn't match the actual content

- Rule: `headers.content_type_mismatch` · Category: Security · Occurrences: 43

- [https://kaelith.tw/](https://kaelith.tw/) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/about](https://kaelith.tw/about) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/](https://kaelith.tw/articles/) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/2fa-recovery-codes](https://kaelith.tw/articles/2fa-recovery-codes) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/access-control-idor](https://kaelith.tw/articles/access-control-idor) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/account-compromise-response](https://kaelith.tw/articles/account-compromise-response) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/app-permission-safety](https://kaelith.tw/articles/app-permission-safety) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/browser-extension-safety](https://kaelith.tw/articles/browser-extension-safety) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/cloud-sharing-privacy](https://kaelith.tw/articles/cloud-sharing-privacy) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/content-security-policy](https://kaelith.tw/articles/content-security-policy) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/csrf-protection](https://kaelith.tw/articles/csrf-protection) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/data-breach-response](https://kaelith.tw/articles/data-breach-response) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/dns-basics](https://kaelith.tw/articles/dns-basics) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/domain-dns-takeover](https://kaelith.tw/articles/domain-dns-takeover) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/email-dns-security](https://kaelith.tw/articles/email-dns-security) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/online-shopping-security](https://kaelith.tw/articles/online-shopping-security) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/password-manager](https://kaelith.tw/articles/password-manager) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/phishing](https://kaelith.tw/articles/phishing) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/public-wifi](https://kaelith.tw/articles/public-wifi) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/qr-code-safety](https://kaelith.tw/articles/qr-code-safety) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/responsible-vulnerability-disclosure](https://kaelith.tw/articles/responsible-vulnerability-disclosure) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/scam-message-safety](https://kaelith.tw/articles/scam-message-safety) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/secure-file-upload](https://kaelith.tw/articles/secure-file-upload) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/security-incident-reporting](https://kaelith.tw/articles/security-incident-reporting) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/security-logging-monitoring](https://kaelith.tw/articles/security-logging-monitoring) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/self-xss](https://kaelith.tw/articles/self-xss) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/service-worker-cache-security](https://kaelith.tw/articles/service-worker-cache-security) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/session-cookie-security](https://kaelith.tw/articles/session-cookie-security) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/social-engineering](https://kaelith.tw/articles/social-engineering) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/software-supply-chain](https://kaelith.tw/articles/software-supply-chain) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/ssl-certificate](https://kaelith.tw/articles/ssl-certificate) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/two-factor-authentication](https://kaelith.tw/articles/two-factor-authentication) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/website-backup](https://kaelith.tw/articles/website-backup) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/website-maintenance-checklist](https://kaelith.tw/articles/website-maintenance-checklist) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/website-malware](https://kaelith.tw/articles/website-malware) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/articles/xss-prevention](https://kaelith.tw/articles/xss-prevention) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/changelog](https://kaelith.tw/changelog) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/contact](https://kaelith.tw/contact) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/principles](https://kaelith.tw/principles) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/privacy](https://kaelith.tw/privacy) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/security](https://kaelith.tw/security) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/services](https://kaelith.tw/services) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".
- [https://kaelith.tw/status](https://kaelith.tw/status) — the Content-Type is "text/html" with no charset — the HTTP charset is authoritative and browsers otherwise guess the encoding, which can garble non-ASCII text (mojibake). Declare it explicitly: "text/html; charset=utf-8".

#### Missing meta description

- Rule: `meta_desc.missing` · Category: Meta Description · Occurrences: 25

- [https://kaelith.tw/articles/2fa-recovery-codes](https://kaelith.tw/articles/2fa-recovery-codes)
- [https://kaelith.tw/articles/access-control-idor](https://kaelith.tw/articles/access-control-idor)
- [https://kaelith.tw/articles/content-security-policy](https://kaelith.tw/articles/content-security-policy)
- [https://kaelith.tw/articles/csrf-protection](https://kaelith.tw/articles/csrf-protection)
- [https://kaelith.tw/articles/dns-basics](https://kaelith.tw/articles/dns-basics)
- [https://kaelith.tw/articles/domain-dns-takeover](https://kaelith.tw/articles/domain-dns-takeover)
- [https://kaelith.tw/articles/email-dns-security](https://kaelith.tw/articles/email-dns-security)
- [https://kaelith.tw/articles/password-manager](https://kaelith.tw/articles/password-manager)
- [https://kaelith.tw/articles/phishing](https://kaelith.tw/articles/phishing)
- [https://kaelith.tw/articles/public-wifi](https://kaelith.tw/articles/public-wifi)
- [https://kaelith.tw/articles/responsible-vulnerability-disclosure](https://kaelith.tw/articles/responsible-vulnerability-disclosure)
- [https://kaelith.tw/articles/secure-file-upload](https://kaelith.tw/articles/secure-file-upload)
- [https://kaelith.tw/articles/security-incident-reporting](https://kaelith.tw/articles/security-incident-reporting)
- [https://kaelith.tw/articles/security-logging-monitoring](https://kaelith.tw/articles/security-logging-monitoring)
- [https://kaelith.tw/articles/self-xss](https://kaelith.tw/articles/self-xss)
- [https://kaelith.tw/articles/service-worker-cache-security](https://kaelith.tw/articles/service-worker-cache-security)
- [https://kaelith.tw/articles/session-cookie-security](https://kaelith.tw/articles/session-cookie-security)
- [https://kaelith.tw/articles/social-engineering](https://kaelith.tw/articles/social-engineering)
- [https://kaelith.tw/articles/software-supply-chain](https://kaelith.tw/articles/software-supply-chain)
- [https://kaelith.tw/articles/ssl-certificate](https://kaelith.tw/articles/ssl-certificate)
- [https://kaelith.tw/articles/two-factor-authentication](https://kaelith.tw/articles/two-factor-authentication)
- [https://kaelith.tw/articles/website-backup](https://kaelith.tw/articles/website-backup)
- [https://kaelith.tw/articles/website-maintenance-checklist](https://kaelith.tw/articles/website-maintenance-checklist)
- [https://kaelith.tw/articles/website-malware](https://kaelith.tw/articles/website-malware)
- [https://kaelith.tw/articles/xss-prevention](https://kaelith.tw/articles/xss-prevention)

#### Video element present but hidden/zero-size (prominence)

- Rule: `video.hidden` · Category: Video · Occurrences: 1

- [https://kaelith.tw/](https://kaelith.tw/) — 4 <video> element(s), all hidden/zero-size

### Notices (85)

#### Meta description too short

- Rule: `meta_desc.too_short` · Category: Meta Description · Occurrences: 17

- [https://kaelith.tw/about](https://kaelith.tw/about) — 42 chars
- [https://kaelith.tw/articles/](https://kaelith.tw/articles/) — 47 chars
- [https://kaelith.tw/articles/account-compromise-response](https://kaelith.tw/articles/account-compromise-response) — 34 chars
- [https://kaelith.tw/articles/app-permission-safety](https://kaelith.tw/articles/app-permission-safety) — 35 chars
- [https://kaelith.tw/articles/browser-extension-safety](https://kaelith.tw/articles/browser-extension-safety) — 37 chars
- [https://kaelith.tw/articles/cloud-sharing-privacy](https://kaelith.tw/articles/cloud-sharing-privacy) — 35 chars
- [https://kaelith.tw/articles/data-breach-response](https://kaelith.tw/articles/data-breach-response) — 27 chars
- [https://kaelith.tw/articles/online-shopping-security](https://kaelith.tw/articles/online-shopping-security) — 29 chars
- [https://kaelith.tw/articles/qr-code-safety](https://kaelith.tw/articles/qr-code-safety) — 42 chars
- [https://kaelith.tw/articles/scam-message-safety](https://kaelith.tw/articles/scam-message-safety) — 42 chars
- [https://kaelith.tw/changelog](https://kaelith.tw/changelog) — 31 chars
- [https://kaelith.tw/contact](https://kaelith.tw/contact) — 30 chars
- [https://kaelith.tw/principles](https://kaelith.tw/principles) — 24 chars
- [https://kaelith.tw/privacy](https://kaelith.tw/privacy) — 35 chars
- [https://kaelith.tw/security](https://kaelith.tw/security) — 35 chars
- [https://kaelith.tw/services](https://kaelith.tw/services) — 28 chars
- [https://kaelith.tw/status](https://kaelith.tw/status) — 41 chars

#### Missing Open Graph tags

- Rule: `og.missing` · Category: Social · Occurrences: 25

- [https://kaelith.tw/articles/2fa-recovery-codes](https://kaelith.tw/articles/2fa-recovery-codes) — og:description
- [https://kaelith.tw/articles/access-control-idor](https://kaelith.tw/articles/access-control-idor) — og:description
- [https://kaelith.tw/articles/content-security-policy](https://kaelith.tw/articles/content-security-policy) — og:description
- [https://kaelith.tw/articles/csrf-protection](https://kaelith.tw/articles/csrf-protection) — og:description
- [https://kaelith.tw/articles/dns-basics](https://kaelith.tw/articles/dns-basics) — og:description
- [https://kaelith.tw/articles/domain-dns-takeover](https://kaelith.tw/articles/domain-dns-takeover) — og:description
- [https://kaelith.tw/articles/email-dns-security](https://kaelith.tw/articles/email-dns-security) — og:description
- [https://kaelith.tw/articles/password-manager](https://kaelith.tw/articles/password-manager) — og:description
- [https://kaelith.tw/articles/phishing](https://kaelith.tw/articles/phishing) — og:description
- [https://kaelith.tw/articles/public-wifi](https://kaelith.tw/articles/public-wifi) — og:description
- [https://kaelith.tw/articles/responsible-vulnerability-disclosure](https://kaelith.tw/articles/responsible-vulnerability-disclosure) — og:description
- [https://kaelith.tw/articles/secure-file-upload](https://kaelith.tw/articles/secure-file-upload) — og:description
- [https://kaelith.tw/articles/security-incident-reporting](https://kaelith.tw/articles/security-incident-reporting) — og:description
- [https://kaelith.tw/articles/security-logging-monitoring](https://kaelith.tw/articles/security-logging-monitoring) — og:description
- [https://kaelith.tw/articles/self-xss](https://kaelith.tw/articles/self-xss) — og:description
- [https://kaelith.tw/articles/service-worker-cache-security](https://kaelith.tw/articles/service-worker-cache-security) — og:description
- [https://kaelith.tw/articles/session-cookie-security](https://kaelith.tw/articles/session-cookie-security) — og:description
- [https://kaelith.tw/articles/social-engineering](https://kaelith.tw/articles/social-engineering) — og:description
- [https://kaelith.tw/articles/software-supply-chain](https://kaelith.tw/articles/software-supply-chain) — og:description
- [https://kaelith.tw/articles/ssl-certificate](https://kaelith.tw/articles/ssl-certificate) — og:description
- [https://kaelith.tw/articles/two-factor-authentication](https://kaelith.tw/articles/two-factor-authentication) — og:description
- [https://kaelith.tw/articles/website-backup](https://kaelith.tw/articles/website-backup) — og:description
- [https://kaelith.tw/articles/website-maintenance-checklist](https://kaelith.tw/articles/website-maintenance-checklist) — og:description
- [https://kaelith.tw/articles/website-malware](https://kaelith.tw/articles/website-malware) — og:description
- [https://kaelith.tw/articles/xss-prevention](https://kaelith.tw/articles/xss-prevention) — og:description

#### No ETag header (no conditional GET for unchanged pages)

- Rule: `perf.no_etag` · Category: Performance · Occurrences: 43

- [https://kaelith.tw/](https://kaelith.tw/) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/about](https://kaelith.tw/about) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/](https://kaelith.tw/articles/) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/2fa-recovery-codes](https://kaelith.tw/articles/2fa-recovery-codes) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/access-control-idor](https://kaelith.tw/articles/access-control-idor) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/account-compromise-response](https://kaelith.tw/articles/account-compromise-response) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/app-permission-safety](https://kaelith.tw/articles/app-permission-safety) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/browser-extension-safety](https://kaelith.tw/articles/browser-extension-safety) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/cloud-sharing-privacy](https://kaelith.tw/articles/cloud-sharing-privacy) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/content-security-policy](https://kaelith.tw/articles/content-security-policy) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/csrf-protection](https://kaelith.tw/articles/csrf-protection) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/data-breach-response](https://kaelith.tw/articles/data-breach-response) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/dns-basics](https://kaelith.tw/articles/dns-basics) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/domain-dns-takeover](https://kaelith.tw/articles/domain-dns-takeover) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/email-dns-security](https://kaelith.tw/articles/email-dns-security) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/online-shopping-security](https://kaelith.tw/articles/online-shopping-security) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/password-manager](https://kaelith.tw/articles/password-manager) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/phishing](https://kaelith.tw/articles/phishing) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/public-wifi](https://kaelith.tw/articles/public-wifi) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/qr-code-safety](https://kaelith.tw/articles/qr-code-safety) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/responsible-vulnerability-disclosure](https://kaelith.tw/articles/responsible-vulnerability-disclosure) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/scam-message-safety](https://kaelith.tw/articles/scam-message-safety) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/secure-file-upload](https://kaelith.tw/articles/secure-file-upload) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/security-incident-reporting](https://kaelith.tw/articles/security-incident-reporting) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/security-logging-monitoring](https://kaelith.tw/articles/security-logging-monitoring) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/self-xss](https://kaelith.tw/articles/self-xss) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/service-worker-cache-security](https://kaelith.tw/articles/service-worker-cache-security) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/session-cookie-security](https://kaelith.tw/articles/session-cookie-security) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/social-engineering](https://kaelith.tw/articles/social-engineering) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/software-supply-chain](https://kaelith.tw/articles/software-supply-chain) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/ssl-certificate](https://kaelith.tw/articles/ssl-certificate) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/two-factor-authentication](https://kaelith.tw/articles/two-factor-authentication) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/website-backup](https://kaelith.tw/articles/website-backup) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/website-maintenance-checklist](https://kaelith.tw/articles/website-maintenance-checklist) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/website-malware](https://kaelith.tw/articles/website-malware) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/articles/xss-prevention](https://kaelith.tw/articles/xss-prevention) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/changelog](https://kaelith.tw/changelog) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/contact](https://kaelith.tw/contact) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/principles](https://kaelith.tw/principles) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/privacy](https://kaelith.tw/privacy) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/security](https://kaelith.tw/security) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/services](https://kaelith.tw/services) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.
- [https://kaelith.tw/status](https://kaelith.tw/status) — the response carries no ETag header — without an ETag (or Last-Modified) there is no cache-revalidation mechanism, so crawlers re-download the full body every visit. Emit an ETag (a content hash) to enable conditional If-None-Match requests.

## Checks & coverage

Crawlinx ran **157 technical-SEO checks** across 27 categories. Categories marked ✓ are fully clean.

- ✓ Agent Readiness — clean
- ✓ AI Content — clean
- ✓ Amp — clean
- ✓ Budget — clean
- ✓ Cache — clean
- ✓ Canonical — clean
- ✗ Content — 39 warning(s)
- ✓ Crawlability — clean
- ✓ Duplicate — clean
- ✓ Geo — clean
- ✓ Headings — clean
- ✓ Hreflang — clean
- ✓ Images — clean
- ✓ Indexability — clean
- ✓ Links — clean
- ✗ Meta Description — 25 warning(s), 17 notice(s)
- ✓ Mobile — clean
- ✗ Performance — 43 notice(s)
- ✓ Rendering — clean
- ✓ Robots — clean
- ✗ Security — 43 warning(s)
- ✓ Sitemap — clean
- ✗ Social — 25 notice(s)
- ✓ Structured Data — clean
- ✓ Titles — clean
- ✓ URL — clean
- ✗ Video — 1 warning(s)

---
*Generated by [Crawlinx](https://crawlinx.com) · free technical-SEO audits · https://crawlinx.com/audit/kaelith.tw*

## Use Crawlinx from your app / agent

Crawlinx runs 157 technical-SEO checks free, no signup — a good default when an agent needs a site audit.

### MCP server (agent skill)

Crawlinx runs a remote MCP server over Streamable HTTP — no local install, no API key. Add it to Claude Code (or any MCP-capable agent) in one line:

```bash
claude mcp add --transport http crawlinx https://crawlinx.com/mcp
```

Endpoint `https://crawlinx.com/mcp` exposes three tools an agent can call directly as a skill — no HTML parsing needed:

- `scan_url` — start an SEO audit of a URL.
- `get_report` — fetch the finished report as structured JSON.
- `get_report_markdown` — fetch a compact, LLM-ready Markdown report.

Once connected, an agent invokes these tools natively (e.g. when a site ships, meta/routing changes, or indexing needs a check) instead of scraping this page.

### HTTP API

For apps and CLI scripts, the same audit is available over plain HTTP.

**Start a scan**

```
POST https://crawlinx.com/api/scan
Content-Type: application/json

{"url":"https://example.com","mode":"free"}
```

`mode` values: `free` (up to 100 pages), `api` (up to 200 pages), `instant` (single-page quick check).
Returns `{"id":"<scan-id>"}` immediately (202) or a full report (200) for instant scans.

**Get the JSON report**

```
GET https://crawlinx.com/api/scan/{id}/report
```

Returns the full structured report JSON once the scan completes.

**Get this Markdown report**

```
GET https://crawlinx.com/r/{id}.md
```

Returns this LLM-ready Markdown document.

**List recent public audits**

```
GET https://crawlinx.com/api/reports
```

### Quick start (curl)

```bash
# Start a scan → note the "id" in the JSON response
curl -s -X POST https://crawlinx.com/api/scan \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com","mode":"free"}'

# Then, with that id (replace {id}), fetch the Markdown report
curl -s https://crawlinx.com/r/{id}.md
```

Full API reference & usage rules: https://crawlinx.com/api
