katman-mcp 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -42
- package/dist/license.js +201 -12
- package/dist/meta.js +25 -13
- package/dist/plans.js +13 -6
- package/dist/tools/account/account.js +19 -10
- package/dist/tools/account/cli.js +4 -3
- package/dist/tools/account/index.js +1 -1
- package/dist/tools/account/upsell.js +156 -39
- package/dist/tools/crawl/audit/report.js +2 -2
- package/dist/tools/crawl/cli.js +18 -6
- package/dist/tools/crawl/index.js +39 -8
- package/dist/tools/crawl/scan/framework.js +4 -1
- package/dist/tools/method/core/lint.js +15 -1
- package/dist/tools/method/core/prompt.js +2 -1
- package/dist/tools/method/data/_store.js +17 -0
- package/dist/tools/method/data/anatomy.js +12 -141
- package/dist/tools/method/data/appendices.js +22 -202
- package/dist/tools/method/data/cloudflare.js +28 -192
- package/dist/tools/method/data/evidence.js +18 -137
- package/dist/tools/method/data/geo-jobs.js +8 -128
- package/dist/tools/method/data/landing.js +14 -67
- package/dist/tools/method/data/lessons.js +16 -127
- package/dist/tools/method/data/measurement.js +38 -142
- package/dist/tools/method/data/offsite.js +16 -148
- package/dist/tools/method/data/pages.js +16 -167
- package/dist/tools/method/data/prompts.js +8 -633
- package/dist/tools/method/data/publish.js +14 -113
- package/dist/tools/method/data/research.js +14 -131
- package/dist/tools/method/data/roadmap.js +12 -105
- package/dist/tools/method/data/traps.js +6 -74
- package/dist/tools/method/data/verify.js +12 -88
- package/dist/tools/method/data/viral-list.js +12 -39
- package/dist/tools/method/lib/prompt-lookup.js +18 -0
- package/dist/tools/method/mcp/resources.js +4 -3
- package/dist/tools/visibility/index.js +2 -2
- package/dist/tools/visibility/monitoring.js +3 -0
- package/package.json +5 -3
- package/server.json +3 -3
|
@@ -1,113 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
where: "Bing Webmaster Tools",
|
|
19
|
-
what: {
|
|
20
|
-
en: "Add the site (import it from Search Console, or verify with a meta tag); submit the sitemap; paste URLs line by line in “URL Submission”. The AI Performance report (since Feb 2026) shows Copilot citations and grounding queries.",
|
|
21
|
-
tr: "Siteyi ekleyin (Search Console’dan içe aktararak ya da meta etiketle doğrulayarak); sitemap gönderin; “URL Submission” ile adresleri satır satır yapıştırın. AI Performance raporu (Şubat 2026’dan beri) Copilot alıntılarını ve kaynak sorgularını gösterir.",
|
|
22
|
-
},
|
|
23
|
-
note: { en: "100 URLs a day. Copilot reads from Bing.", tr: "Günde 100 adres. Copilot Bing’den okur." },
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
where: "IndexNow",
|
|
27
|
-
what: {
|
|
28
|
-
en: "Publish the key file at the root; on every release, submit only the URLs whose text changed.",
|
|
29
|
-
tr: "Anahtar dosyasını kökte yayınlayın; her yayında yalnızca metni değişen adresleri gönderin.",
|
|
30
|
-
},
|
|
31
|
-
note: {
|
|
32
|
-
en: "The sample site used to submit all 173 pages on every release; we cut it to the changed ones. Reaches Bing, Yandex, Naver, Seznam and Yep.",
|
|
33
|
-
tr: "Örnek site önceden her yayında 173 sayfanın hepsini gönderiyordu; yalnızca değişenlere indirdik. Bing, Yandex, Naver, Seznam ve Yep’e ulaşır.",
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
where: "Brave Search",
|
|
38
|
-
what: {
|
|
39
|
-
en: "Enter one URL at a time at search.brave.com/submit-url.",
|
|
40
|
-
tr: "search.brave.com/submit-url adresine her seferinde bir adres girin.",
|
|
41
|
-
},
|
|
42
|
-
note: {
|
|
43
|
-
en: "No account needed. Doesn't support IndexNow; follows robots.txt rules written for Googlebot. Claude answers from Brave's index.",
|
|
44
|
-
tr: "Hesap gerekmiyor. IndexNow’u desteklemiyor; Googlebot için yazılmış robots.txt kurallarına uyuyor. Claude Brave’in dizininden cevaplıyor.",
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
where: "CDN / firewall",
|
|
49
|
-
what: {
|
|
50
|
-
en: "Check the AI bot block, Bot Fight Mode, AI Labyrinth and managed robots.txt settings; turn off e-mail obfuscation.",
|
|
51
|
-
tr: "Yapay zekâ botu engeli, bot mücadele modu, AI Labyrinth ve yönetilen robots.txt ayarlarını kontrol edin; e-posta gizlemeyi kapatın.",
|
|
52
|
-
},
|
|
53
|
-
note: { en: "On katman.pro the AI training-bot block was on; we turned it off (ch. 6).", tr: "katman.pro’da AI eğitim botu engeli açıktı; kapattık (06. bölüm)." },
|
|
54
|
-
},
|
|
55
|
-
];
|
|
56
|
-
export const NEW_PAGE_CHECKLIST = [
|
|
57
|
-
{ en: "The page is in the sitemap, gets a link from at least one page, and passed the P14 check.", tr: "Sayfa sitemap’te, en az bir sayfadan link alıyor, P14 kontrolünden geçti." },
|
|
58
|
-
{ en: "Only this URL (and the pages whose links changed) went to IndexNow.", tr: "IndexNow’a yalnızca bu adres (ve linki değişen sayfalar) gitti." },
|
|
59
|
-
{ en: "Search Console: URL Inspection → request indexing.", tr: "Search Console’da URL denetimi → dizine ekleme isteği." },
|
|
60
|
-
{ en: "Bing “URL Submission” and Brave “submit-url”.", tr: "Bing “URL Submission” ve Brave “submit-url”." },
|
|
61
|
-
{
|
|
62
|
-
en: "Ask ChatGPT the question the page answers again 14 days later; write it in the measurement table.",
|
|
63
|
-
tr: "Sayfanın cevap verdiği soruyu 14 gün sonra ChatGPT’ye tekrar sorun; ölçüm tablosuna yazın.",
|
|
64
|
-
},
|
|
65
|
-
];
|
|
66
|
-
export const AFTER_14_DAYS = {
|
|
67
|
-
en: "Search Console → Pages: “Discovered – currently not indexed” is mostly missing internal links (the cause for 35 pages on the sample site). “Crawled – currently not indexed” suggests the page isn't different enough: stop publishing new pages from that template. In analytics, look at the ChatGPT channel; trust the utm_source=chatgpt.com tag, not the referrer.",
|
|
68
|
-
tr: "Search Console → Sayfa sayısı: “Keşfedildi, şu anda dizine eklenmedi” çoğunlukla iç link eksikliğidir (örnek sitede 35 sayfanın sebebi buydu). “Tarandı, şu anda dizine eklenmedi” sayfanın yeterince farklı olmadığını düşündürür; o şablonla yeni sayfa basmayı durdurun. Analitikte ChatGPT kanalına bakın; referrer’a değil, utm_source=chatgpt.com etiketine güvenin.",
|
|
69
|
-
};
|
|
70
|
-
export const INDEXING_STORY = [
|
|
71
|
-
{
|
|
72
|
-
engine: "Google",
|
|
73
|
-
text: {
|
|
74
|
-
en: "Setup: domain property (DNS; covers every subdomain and protocol), sitemap submitted. Diagnosis on 24 Sep: 64 pages indexed, 41 not. 2 of the 41 were correct (login noindex, www redirect). The other 39 weren't technical errors: 35 were “discovered – not indexed”, 4 “crawled – not indexed”; URL Inspection said “no referring page detected”. Category pages got ~7 internal links, indexed ones 140–170. Fix: footer links to all 34 category pages, written content on the quiz page, lastmod moved only for pages whose words changed, sitemap resubmitted, a dead 2016 sitemap from the domain's previous owner removed, indexing requested for priority URLs (daily quota ~7–10). Result: new pages started getting indexed the same day.",
|
|
75
|
-
tr: "Kurulum: alan adı mülkü (DNS kaydı; bütün alt alan adlarını ve protokolleri kapsar), sitemap gönderimi. Teşhis, 24 Eylül: 64 sayfa dizinde, 41 değil. 41’in 2’si doğruydu (giriş sayfası noindex, www yönlendirmesi). Kalan 39 teknik hata değildi: 35’i “keşfedildi, şu anda dizine eklenmedi”, 4’ü “tarandı, dizine eklenmedi”; URL denetimi “yönlendiren sayfa algılanmadı” dedi. Kategori sayfaları ~7 iç link alıyordu, dizindekiler 140–170. Düzeltme: her sayfanın altbilgisinden 34 kategori sayfasına link; test sayfasına yazılı içerik; yalnızca kelimesi değişen sayfanın lastmod’u ilerledi; sitemap yeniden gönderildi; alan adının önceki sahibinden kalma 2016 tarihli ölü sitemap kaydı silindi; öncelikli adresler için dizine ekleme istendi (günlük kota ~7–10). Sonuç: yeni sayfalar aynı gün dizine girmeye başladı.",
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
engine: "Bing (Copilot)",
|
|
80
|
-
text: {
|
|
81
|
-
en: "Verified with a meta tag, sitemap submitted. The Bing URL Submission API wired into the release script: every URL once, the most important first, again when lastmod changes; daily quota ~100; submitted URLs kept in a file. Pages stayed “discovered – not crawled” for a long time; ChatGPT sent traffic anyway.",
|
|
82
|
-
tr: "Meta etiketiyle doğrulandı, sitemap gönderildi. Bing URL Submission API yayın betiğine bağlandı: her adres bir kez, en önemliler önce, lastmod değişince tekrar; günlük ~100 kota; gönderilenler bir dosyada tutuluyor. Sayfalar uzun süre “keşfedildi, taranmadı” kaldı; ChatGPT buna rağmen trafik gönderdi.",
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
engine: "IndexNow",
|
|
87
|
-
text: {
|
|
88
|
-
en: "The key file is on the site and runs by itself after each release; it reaches Bing, Yandex, Naver, Seznam and Yep. For the first 3 days all 173 URLs went out on every release (~20 times); now only new URLs or those whose lastmod changed.",
|
|
89
|
-
tr: "Anahtar dosyası sitede; yayından sonra kendiliğinden çalışır; Bing, Yandex, Naver, Seznam ve Yep’e ulaşır. İlk 3 günde her yayında 173 adresin hepsi gidiyordu (~20 kez); artık yalnızca yeni ya da lastmod’u değişenler.",
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
engine: "Brave",
|
|
94
|
-
text: {
|
|
95
|
-
en: "Doesn't support IndexNow; the whole sitemap was submitted page by page via search.brave.com/submit-url. Brave has no user-agent of its own and doesn't crawl pages Googlebot can't: your robots.txt rules for Googlebot apply to Brave too. To remove a page from its index, use noindex, not robots.txt.",
|
|
96
|
-
tr: "IndexNow’u desteklemiyor; search.brave.com/submit-url üzerinden sayfa sayfa gönderildi (bütün sitemap). Brave kendine ait bir user-agent kullanmıyor ve Googlebot’un tarayamadığı sayfayı taramıyor: Googlebot için yazdığınız robots.txt kuralları Brave için de geçerli. Dizinden çıkarmak için robots.txt değil noindex kullanın.",
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
engine: "Baidu",
|
|
101
|
-
text: {
|
|
102
|
-
en: "Considered and postponed: it needs Chinese content, a phone-verified account, local payment and compliance with China's generative-AI rules.",
|
|
103
|
-
tr: "Değerlendirildi, ertelendi: Çince içerik, telefonla doğrulanmış hesap, yerel ödeme ve Çin’in üretken yapay zekâ kuralları gerekiyor.",
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
engine: "Google (preferred sources)",
|
|
108
|
-
text: {
|
|
109
|
-
en: "A Google “preferred sources” link was added to the footer: users can pick your site as a preferred source in Google.",
|
|
110
|
-
tr: "Altbilgiye Google’ın “tercih edilen kaynaklar” linki eklendi: kullanıcı Google’da sitenizi tercih ettiği kaynak olarak seçebiliyor.",
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
];
|
|
1
|
+
// Filled from katman.pro at run time for a paid key (see _store.js); the package carries no method text.
|
|
2
|
+
import { onMethod } from "./_store.js";
|
|
3
|
+
export let AFTER_14_DAYS = {};
|
|
4
|
+
export let INDEXING_STORY = [];
|
|
5
|
+
export let NEW_PAGE_CHECKLIST = [];
|
|
6
|
+
export let NOTIFY_INTRO = {};
|
|
7
|
+
export let NOTIFY_TARGETS = [];
|
|
8
|
+
onMethod((d) => {
|
|
9
|
+
if (d.AFTER_14_DAYS !== undefined) AFTER_14_DAYS = d.AFTER_14_DAYS;
|
|
10
|
+
if (d.INDEXING_STORY !== undefined) INDEXING_STORY = d.INDEXING_STORY;
|
|
11
|
+
if (d.NEW_PAGE_CHECKLIST !== undefined) NEW_PAGE_CHECKLIST = d.NEW_PAGE_CHECKLIST;
|
|
12
|
+
if (d.NOTIFY_INTRO !== undefined) NOTIFY_INTRO = d.NOTIFY_INTRO;
|
|
13
|
+
if (d.NOTIFY_TARGETS !== undefined) NOTIFY_TARGETS = d.NOTIFY_TARGETS;
|
|
14
|
+
});
|
|
@@ -1,131 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
text: {
|
|
16
|
-
en: "In a long question describing what the user has, what they can't do and what they want, ChatGPT recommended the sample site (26 and 28 September). On the same category's “best … 2026” question it didn't.",
|
|
17
|
-
tr: "Kullanıcının elinde ne olduğunu, neyi yapamadığını ve ne istediğini anlatan uzun bir soruda ChatGPT örnek sitemizi önerdi (26 ve 28 Eylül). Aynı kategorinin “en iyi … 2026” sorusunda önermedi.",
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
n: 2,
|
|
23
|
-
title: { en: "Ask the assistants and record the answers", tr: "Asistana sorun ve cevabı kaydedin" },
|
|
24
|
-
how: {
|
|
25
|
-
en: "Ask each question in ChatGPT logged out, with web search on; if you can, in Claude, Gemini and Perplexity too. Record in a table whom it recommends, which page it cites as its source and whether it mentions you. Answers change from session to session; a single measurement is a “low sample” — ask the same questions again 14 days later.",
|
|
26
|
-
tr: "Her soruyu ChatGPT’ye oturum açmadan ve web araması açıkken sorun; mümkünse Claude, Gemini ve Perplexity’ye de. Kimi önerdiğini, hangi sayfayı kaynak gösterdiğini ve sizi anıp anmadığını bir tabloya yazın. Cevaplar oturumdan oturuma değişir; tek ölçüm “düşük örnek”tir, 14 gün sonra aynı soruları tekrar sorun.",
|
|
27
|
-
},
|
|
28
|
-
extra: {
|
|
29
|
-
label: { en: "Output", tr: "Çıktı" },
|
|
30
|
-
text: {
|
|
31
|
-
en: "A competitor list (whom the assistant names) and a source list (the pages the assistant read). Your comparison guide (P7) is written from this list.",
|
|
32
|
-
tr: "Rakip listesi (asistanın saydıkları) ve kaynak listesi (asistanın okuduğu sayfalar). Karşılaştırma rehberiniz (P7) bu listeyle yazılır.",
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
n: 3,
|
|
38
|
-
title: { en: "The words people type into Google", tr: "İnsanların Google’a yazdığı kelimeler" },
|
|
39
|
-
how: {
|
|
40
|
-
en: "No paid tool needed: Google autocomplete and the “People also ask” box; keyword research in Bing Webmaster Tools; once the site is live, Search Console → Performance → Queries. Name page URLs and titles with these words: the Turkish version of katman.pro's “AI visibility consulting” page became “geo-danismanligi”, because that's how Turkish buyers type it.",
|
|
41
|
-
tr: "Ücretli araç şart değil: Google’ın otomatik tamamlaması ve “Benzer sorular” kutusu; Bing Webmaster Tools’taki anahtar kelime araştırması; site yayındaysa Search Console → Performans → Sorgular. Sayfa adreslerini ve başlıklarını bu kelimelerle adlandırın: katman.pro’da “AI visibility consulting” sayfasının Türkçesi “geo-danismanligi” oldu, çünkü Türk alıcı öyle yazıyor.",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
n: 4,
|
|
46
|
-
title: { en: "Your one sentence and your “not-X” note", tr: "Tek cümleniz ve “X değildir” notunuz" },
|
|
47
|
-
how: {
|
|
48
|
-
en: "Pattern: (1) what the customer brings, (2) what you do, (3) what they get, (4) which fear is unnecessary. An invented example: “Upload your invoice. We move the line items into your accounting software in 30 seconds and flag the ones that don't match. Your document is never stored.” The sample site's real sentence had the same structure; in two sessions on 28 September ChatGPT repeated all four parts.",
|
|
49
|
-
tr: "Kalıp: (1) Müşteri ne getirir, (2) siz ne yaparsınız, (3) eline ne geçer, (4) hangi korkusu gereksiz. Uydurma bir örnek: “Faturanı yükle. Kalemleri 30 saniyede muhasebe programına aktarırız ve eşleşmeyenleri işaretleriz. Belgen hiçbir yerde saklanmaz.” Örnek sitenin gerçek cümlesi aynı yapıdaydı; ChatGPT 28 Eylül’deki iki oturumda dört parçanın dördünü de tekrar etti.",
|
|
50
|
-
},
|
|
51
|
-
extra: {
|
|
52
|
-
label: { en: "Not-X", tr: "X değildir" },
|
|
53
|
-
text: {
|
|
54
|
-
en: "Ask ChatGPT “What is [your brand]?”. If you get confused with something else, say so explicitly. On 22 September Perplexity mistook the sample site for another company's product with the same short name; with a distinctive two-word name and the sentence “we're not that product”, it identified the site correctly on 24 September.",
|
|
55
|
-
tr: "ChatGPT’ye “[markanız] nedir?” diye sorun. Başka bir şeyle karışıyorsa açıkça yazın. Perplexity 22 Eylül’de örnek sitemizi aynı kısa adı taşıyan başka bir şirketin ürünü sandı; iki kelimelik ayırt edici ad ve “o ürün değiliz” cümlesiyle 24 Eylül’de doğru tanıdı.",
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
];
|
|
60
|
-
export const RESEARCH_EXERCISE = {
|
|
61
|
-
en: "Today, ask ChatGPT two questions without logging in: “What is [your brand]?” and one question describing your customer's most common situation. Save the answers with screenshots; in 30 days you'll ask the same questions and compare.",
|
|
62
|
-
tr: "Bugün ChatGPT’ye oturum açmadan iki soru sorun: “[markanız] nedir?” ve müşterinizin en sık yaşadığı durumu anlatan bir soru. Cevapları ekran görüntüsüyle kaydedin; 30 gün sonra aynı soruları sorup karşılaştıracaksınız.",
|
|
63
|
-
};
|
|
64
|
-
/** The book's research.md template (fill it in, give it to your coding tool). */
|
|
65
|
-
export const RESEARCH_MD_TEMPLATE = {
|
|
66
|
-
en: `# research.md
|
|
67
|
-
## Brand
|
|
68
|
-
Name: [one distinctive name] Is not: [what it gets confused with]
|
|
69
|
-
One sentence: [brings] + [we do] + [they get] + [fear is unnecessary]
|
|
70
|
-
Pricing: [plan: price, exactly as on the site]
|
|
71
|
-
|
|
72
|
-
## Customer situations (10–12, unbranded)
|
|
73
|
-
1. "[the sentence your customer would type into ChatGPT]" → page: /[url]
|
|
74
|
-
2. ...
|
|
75
|
-
|
|
76
|
-
## Assistant measurement ([date], logged out, web search on)
|
|
77
|
-
| question | assistant | mentioned us? | whom it recommended | page it cited |
|
|
78
|
-
|
|
79
|
-
## Competitors (each from its own site, with the date checked)
|
|
80
|
-
| name | what it does | price | for whom | source | date |
|
|
81
|
-
|
|
82
|
-
## Proof (verifiable only)
|
|
83
|
-
[number] — [source] — [date]
|
|
84
|
-
|
|
85
|
-
## Search keywords
|
|
86
|
-
[keyword] → [which page]`,
|
|
87
|
-
tr: `# research.md
|
|
88
|
-
## Marka
|
|
89
|
-
Ad: [tek, ayırt edici ad] Değildir: [karıştırıldığı şey]
|
|
90
|
-
Tek cümle: [getirir] + [yaparız] + [eline geçer] + [korku gereksiz]
|
|
91
|
-
Fiyat: [plan: fiyat, sitedeki ile aynı]
|
|
92
|
-
|
|
93
|
-
## Müşteri durumları (10-12, markasız)
|
|
94
|
-
1. "[müşterinin ChatGPT'ye yazacağı cümle]" → sayfa: /[adres]
|
|
95
|
-
2. ...
|
|
96
|
-
|
|
97
|
-
## Asistan ölçümü ([tarih], oturum açmadan, web araması açık)
|
|
98
|
-
| soru | asistan | bizi andı mı | kimi önerdi | kaynak gösterdiği sayfa |
|
|
99
|
-
|
|
100
|
-
## Rakipler (her biri kendi sitesinden, kontrol tarihiyle)
|
|
101
|
-
| ad | ne yapar | fiyat | kime uygun | kaynak | tarih |
|
|
102
|
-
|
|
103
|
-
## Kanıt (yalnızca doğrulanabilir)
|
|
104
|
-
[sayı] — [kaynak] — [tarih]
|
|
105
|
-
|
|
106
|
-
## Aranan kelimeler
|
|
107
|
-
[kelime] → [hangi sayfa]`,
|
|
108
|
-
};
|
|
109
|
-
/** How the agent should fill research without inventing anything (Katman's addition to ch. 7). */
|
|
110
|
-
export const RESEARCH_FILL_GUIDE = {
|
|
111
|
-
en: `Fill it from what the codebase already says, then ask the user for what code can't tell you.
|
|
112
|
-
From the codebase (README, landing page copy, pricing page, legal pages/footer, existing meta tags):
|
|
113
|
-
- brand.name (one distinctive name), brand.category, brand.pricing (exactly as on the pricing page), site.url, site.languages, brand.socials, brand.company and brand.country.
|
|
114
|
-
- a first draft of the one sentence in 4 parts: oneLiner.brings → oneLiner.weDo → oneLiner.gets → oneLiner.fear. Show it to the user.
|
|
115
|
-
Ask the user (never guess these):
|
|
116
|
-
- 10–12 situations: sentences their customers would type into ChatGPT, in the customer's words, without the brand name (from sales calls, support e-mails, reviews).
|
|
117
|
-
- notX: what the brand gets confused with (ask ChatGPT, logged out: "What is <brand>?"). If nothing, write "none".
|
|
118
|
-
- competitors: the names assistants recommend today; take what/price/forWhom from each competitor's own site and record url + checkedAt (YYYY-MM-DD).
|
|
119
|
-
- proof: only verifiable numbers, each with a source and a date.
|
|
120
|
-
Unknown values stay [FILL]. Then call katman_research with mode "update" and your data; once there are ≥3 situations, add generate_questions: true.`,
|
|
121
|
-
tr: `Önce kod tabanının zaten söylediklerinden doldurun, sonra kodun söyleyemediklerini kullanıcıya sorun.
|
|
122
|
-
Kod tabanından (README, açılış sayfası metni, fiyat sayfası, yasal sayfalar/altbilgi, mevcut meta etiketleri):
|
|
123
|
-
- brand.name (tek, ayırt edici ad), brand.category, brand.pricing (fiyat sayfasındakiyle birebir), site.url, site.languages, brand.socials, brand.company ve brand.country.
|
|
124
|
-
- dört parçalı tek cümlenin ilk taslağı: oneLiner.brings → oneLiner.weDo → oneLiner.gets → oneLiner.fear. Kullanıcıya gösterin.
|
|
125
|
-
Kullanıcıya sorun (asla tahmin etmeyin):
|
|
126
|
-
- 10–12 durum: müşterilerinin ChatGPT’ye yazacağı, marka adı geçmeyen, müşterinin kendi kelimeleriyle cümleler (satış görüşmeleri, destek e-postaları, yorumlar).
|
|
127
|
-
- notX: markanın neyle karıştırıldığı (ChatGPT’ye oturum açmadan “<marka> nedir?” diye sorun). Karışmıyorsa "yok" yazın.
|
|
128
|
-
- rakipler: asistanların bugün önerdiği adlar; ne yaptığını, fiyatını, kime uygun olduğunu rakibin kendi sitesinden alın, url ve checkedAt (YYYY-AA-GG) kaydedin.
|
|
129
|
-
- kanıt: yalnızca doğrulanabilir sayılar, her biri kaynağı ve tarihiyle.
|
|
130
|
-
Bilinmeyen değerler [DOLDUR] kalır. Sonra katman_research’ü mode "update" ve verinizle çağırın; en az 3 durum olunca generate_questions: true ekleyin.`,
|
|
131
|
-
};
|
|
1
|
+
// Filled from katman.pro at run time for a paid key (see _store.js); the package carries no method text.
|
|
2
|
+
import { onMethod } from "./_store.js";
|
|
3
|
+
export let RESEARCH_EXERCISE = {};
|
|
4
|
+
export let RESEARCH_FILL_GUIDE = {};
|
|
5
|
+
export let RESEARCH_INTRO = {};
|
|
6
|
+
export let RESEARCH_MD_TEMPLATE = {};
|
|
7
|
+
export let RESEARCH_STEPS = [];
|
|
8
|
+
onMethod((d) => {
|
|
9
|
+
if (d.RESEARCH_EXERCISE !== undefined) RESEARCH_EXERCISE = d.RESEARCH_EXERCISE;
|
|
10
|
+
if (d.RESEARCH_FILL_GUIDE !== undefined) RESEARCH_FILL_GUIDE = d.RESEARCH_FILL_GUIDE;
|
|
11
|
+
if (d.RESEARCH_INTRO !== undefined) RESEARCH_INTRO = d.RESEARCH_INTRO;
|
|
12
|
+
if (d.RESEARCH_MD_TEMPLATE !== undefined) RESEARCH_MD_TEMPLATE = d.RESEARCH_MD_TEMPLATE;
|
|
13
|
+
if (d.RESEARCH_STEPS !== undefined) RESEARCH_STEPS = d.RESEARCH_STEPS;
|
|
14
|
+
});
|
|
@@ -1,105 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
],
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
horizon: { en: "2–4 weeks", tr: "2–4 hafta" },
|
|
17
|
-
items: [
|
|
18
|
-
{ en: "An og:image per page (generated automatically, showing the title and the situation).", tr: "Sayfa başına og:image (başlık ve durum yazan, kendiliğinden üretilen)." },
|
|
19
|
-
{ en: "Inline the critical CSS; merge the two CSS files into one (~150 ms).", tr: "Kritik CSS’i satır içine almak; iki CSS dosyasını bire indirmek (~150 ms)." },
|
|
20
|
-
{ en: "Slim llms.txt down (65 KB, bigger than llms-full.txt): the main product and one link per language; long lists go to llms-full.txt.", tr: "llms.txt’yi inceltmek (65 KB, llms-full.txt’den büyük): ana ürün ve dil başına tek link; uzun listeler llms-full.txt’ye." },
|
|
21
|
-
{ en: "Raise the share of product pages: a new page for every real user situation; slow down template-page production.", tr: "Ürün sayfası oranını artırmak: her gerçek kullanıcı durumu için yeni sayfa; şablon sayfa üretimini yavaşlatmak." },
|
|
22
|
-
{ en: "Outreach to list authors; free directories; a cost decision on paid directories; Reddit's 14-day warm-up.", tr: "Liste yazarlarına ulaşmak; ücretsiz dizinler; ücretli dizinler için maliyet kararı; Reddit’in 14 günlük ısınması." },
|
|
23
|
-
{ en: "A YouTube video for every situation (the signal most strongly associated with AI visibility).", tr: "Her durum için bir YouTube videosu (yapay zekâ görünürlüğüyle en güçlü ilişkili sinyal)." },
|
|
24
|
-
{ en: "Guide hubs per language for translated guides; split the sitemap by template (index rate per template in Search Console).", tr: "Çevrilmiş rehberler için dil başına rehber merkezleri; sitemap’i şablona göre bölmek (Search Console’da şablon başına dizin oranı)." },
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
horizon: { en: "1–3 months", tr: "1–3 ay" },
|
|
29
|
-
items: [
|
|
30
|
-
{ en: "Quotable original data: regular publishing from our own measurements. Assistants and journalists quote original data.", tr: "Alıntılanabilir özgün veri: kendi ölçümlerimizden düzenli yayın. Asistanlar ve gazeteciler özgün veriyi alıntılar." },
|
|
31
|
-
{ en: "Real user reviews (after purchase, unincentivised, unfiltered) on a review platform.", tr: "Gerçek kullanıcı yorumları (satın alma sonrası, teşviksiz, süzülmemiş) bir yorum platformunda." },
|
|
32
|
-
{ en: "A named author: Person schema, bio, sameAs.", tr: "İsimli yazar: Person şeması, biyografi, sameAs." },
|
|
33
|
-
{ en: "A controlled test of the PDFs' effect: publish a new document linking to a new URL that isn't in the sitemap and watch when OAI-SearchBot fetches it.", tr: "PDF’lerin etkisini kontrollü test etmek: sitemap’te olmayan yeni bir adrese link veren yeni bir belge yayınlayıp OAI-SearchBot’un onu ne zaman çektiğini izlemek." },
|
|
34
|
-
{ en: "Real Core Web Vitals once field data (CrUX) exists; Wikidata once independent press and blog mentions exist.", tr: "Saha verisi (CrUX) oluşunca gerçek Core Web Vitals takibi; bağımsız basın ve blog bahsedilmeleri oluşunca Wikidata." },
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
];
|
|
38
|
-
export const FIRST_30_DAYS = [
|
|
39
|
-
{
|
|
40
|
-
week: 1,
|
|
41
|
-
title: { en: "Research, first measurement, audit", tr: "Araştırma, ilk ölçüm, denetim" },
|
|
42
|
-
todo: {
|
|
43
|
-
en: "Fill in research (ch. 7). First measurement with the question set (ch. 15). Test the 6 traps (ch. 5). P0 and P1: an audit without changing code.",
|
|
44
|
-
tr: "research.md’yi doldurun (07). Soru setiyle ilk ölçüm (15). 6 tuzağın testleri (05). P0 ve P1: kodu değiştirmeden denetim.",
|
|
45
|
-
},
|
|
46
|
-
output: { en: "Research file, first measurement, list of problems", tr: "Araştırma dosyası, ilk ölçüm, sorun listesi" },
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
week: 2,
|
|
50
|
-
title: { en: "A technically clean site, announced", tr: "Teknik olarak temiz, bildirilmiş site" },
|
|
51
|
-
todo: {
|
|
52
|
-
en: "P2–P5 and P9–P12: text in HTML, head tags, robots.txt and sitemap, schema, images, links, 404 and preview URLs, speed. Set up Search Console, Bing, IndexNow and Brave (ch. 13). CDN bot settings.",
|
|
53
|
-
tr: "P2–P5 ve P9–P12: metin HTML’de, head etiketleri, robots.txt ve sitemap, schema, görseller, linkler, 404 ve önizleme adresleri, hız. Search Console, Bing, IndexNow ve Brave kurulumu (13). CDN bot ayarları.",
|
|
54
|
-
},
|
|
55
|
-
output: { en: "A technically clean site the search engines have been told about", tr: "Teknik olarak temiz, bildirilmiş site" },
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
week: 3,
|
|
59
|
-
title: { en: "First situation pages live", tr: "İlk durum sayfaları yayında" },
|
|
60
|
-
todo: {
|
|
61
|
-
en: "3–5 situation pages with P6, a comparison guide with P7, llms.txt with P8. Welcome the visitor (ch. 10). Announce every new page.",
|
|
62
|
-
tr: "P6 ile 3–5 durum sayfası, P7 ile karşılaştırma rehberi, P8 ile llms.txt. Ziyaretçiyi karşılama (10). Her yeni sayfayı bildirin.",
|
|
63
|
-
},
|
|
64
|
-
output: { en: "The first situation pages are live", tr: "İlk durum sayfaları yayında" },
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
week: 4,
|
|
68
|
-
title: { en: "Measurement, off-site traces, second measurement", tr: "Ölçüm, site dışı izler, ikinci ölçüm" },
|
|
69
|
-
todo: {
|
|
70
|
-
en: "P13 measurement setup. Traces outside the site (ch. 14): a video, directory texts, an outreach list. On day 14 ask the question set again; check in Search Console why pages aren't indexed. Wire P14 into every release.",
|
|
71
|
-
tr: "P13 ölçüm altyapısı. Site dışı izler (14): bir video, dizin metinleri, ulaşma listesi. 14. günde soru setini tekrar sorun; Search Console’da dizine girmeyen sayfaların sebebine bakın. P14’ü her yayına bağlayın.",
|
|
72
|
-
},
|
|
73
|
-
output: { en: "The second measurement, a plan for the next 60 days", tr: "İkinci ölçüm, sonraki 60 günün planı" },
|
|
74
|
-
},
|
|
75
|
-
];
|
|
76
|
-
/** "Before publishing, on one page" (ch. 19). */
|
|
77
|
-
export const PREPUBLISH_CHECKLIST = [
|
|
78
|
-
{ text: { en: "Research is complete: the one sentence, “not-X”, 10–12 situation questions, competitors, proof.", tr: "research.md dolu: tek cümle, “X değildir”, 10–12 durum sorusu, rakipler, kanıt." }, check: "katman_research (mode show: completeness)" },
|
|
79
|
-
{ text: { en: "The assistants were asked the questions; the answers were recorded with dates.", tr: "Asistanlara sorular soruldu, cevaplar tarihiyle kaydedildi." }, check: "katman_visibility_run / katman_manual_check" },
|
|
80
|
-
{ text: { en: "The text is visible without JavaScript (command 4).", tr: "Metin JavaScript olmadan görünüyor (komut 4)." }, check: "katman_audit_site (wordsJsOff)" },
|
|
81
|
-
{ text: { en: "GPTBot, OAI-SearchBot, ClaudeBot and PerplexityBot get 200 (command 5).", tr: "GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot 200 alıyor (komut 5)." }, check: "katman_audit_site (bot access)" },
|
|
82
|
-
{ text: { en: "On the CDN: the AI bot block, AI Labyrinth and managed robots.txt are off.", tr: "CDN’de yapay zekâ botu engeli, AI Labyrinth, yönetilen robots.txt kapalı." }, check: "manual (ch. 6) + katman_audit_site (bot access)" },
|
|
83
|
-
{ text: { en: "A missing URL returns 404; the preview URL redirects or is noindex.", tr: "Olmayan adres 404; önizleme adresi yönleniyor ya da noindex." }, check: "katman_audit_site (soft 404, preview copies)" },
|
|
84
|
-
{ text: { en: "Every page has a unique title and meta description.", tr: "Her sayfada benzersiz title ve meta açıklama." }, check: "katman_audit_site" },
|
|
85
|
-
{ text: { en: "The canonical points to the page's own full URL; http, www and preview go to one address.", tr: "Canonical kendi tam adresine; http, www ve önizleme tek adrese." }, check: "katman_audit_site (canonicalSelf, redirects)" },
|
|
86
|
-
{ text: { en: "og:image 1200×630 on every page.", tr: "og:image 1200×630, her sayfada." }, check: "katman_audit_site (ogImage)" },
|
|
87
|
-
{ text: { en: "A page for every situation; the first 1–3 sentences answer.", tr: "Her durum için bir sayfa; ilk 1–3 cümle cevap." }, check: "katman_plan + katman_lint_content" },
|
|
88
|
-
{ text: { en: "The one sentence is the same on the page, in the meta description and in llms.txt.", tr: "Tek cümle sayfada, meta açıklamada ve llms.txt’de aynı." }, check: "katman_lint_content (one-sentence check)" },
|
|
89
|
-
{ text: { en: "A sourced, dated guide that names competitors.", tr: "Rakipleri de sayan, kaynaklı, tarihli bir rehber." }, check: "katman_lint_content (page_type comparison)" },
|
|
90
|
-
{ text: { en: "The FAQ is written for the assistant; JSON-LD is valid and matches the page.", tr: "SSS asistan için; JSON-LD geçerli ve sayfayla aynı." }, check: "katman_audit_site (jsonLdErrors)" },
|
|
91
|
-
{ text: { en: "Images have alt, width/height, compression.", tr: "Görsellerde alt, width/height, sıkıştırma." }, check: "katman_scan_code + katman_audit_site" },
|
|
92
|
-
{ text: { en: "No orphan pages; links are <a href>.", tr: "Yetim sayfa yok; linkler <a href>." }, check: "katman_audit_site (internalLinksIn) + katman_scan_code" },
|
|
93
|
-
{ text: { en: "robots.txt closes the app paths, not the site; it has a sitemap line.", tr: "robots.txt uygulama yollarını kapatıyor, siteyi değil; sitemap satırı var." }, check: "katman_audit_site (robots)" },
|
|
94
|
-
{ text: { en: "sitemap.xml has only canonical URLs that return 200; a real lastmod.", tr: "sitemap.xml’de yalnızca 200 dönen, kanonik adresler; gerçek lastmod." }, check: "katman_audit_site (sitemap)" },
|
|
95
|
-
{ text: { en: "Login, checkout and thank-you pages are noindex.", tr: "Giriş, ödeme, teşekkür sayfaları noindex." }, check: "katman_audit_site" },
|
|
96
|
-
{ text: { en: "Lighthouse mobile: LCP ≤ 2.5 s, CLS ≤ 0.1; the HTML is compressed (command 9).", tr: "Lighthouse mobil: LCP ≤ 2,5 sn, CLS ≤ 0,1; HTML sıkıştırılıyor (komut 9)." }, check: "manual (Lighthouse) + katman_audit_site (compression)" },
|
|
97
|
-
{ text: { en: "Search Console, Bing, IndexNow and Brave have been notified.", tr: "Search Console, Bing, IndexNow, Brave’e bildirildi." }, check: "katman_indexnow" },
|
|
98
|
-
{ text: { en: "utm_source=chatgpt.com is its own channel in analytics; bots are counted on the server.", tr: "Analitikte utm_source=chatgpt.com ayrı kanal; botlar sunucuda sayılıyor." }, check: "katman_scan_code (analytics) + katman_generate (snippets)" },
|
|
99
|
-
{ text: { en: "The same questions were asked again after 14 days.", tr: "14 gün sonra aynı sorular yeniden soruldu." }, check: "katman_visibility_run" },
|
|
100
|
-
];
|
|
101
|
-
/** The book's closing offer (kept for reference; tools don't print it). */
|
|
102
|
-
export const DONE_FOR_YOU = {
|
|
103
|
-
en: "If you'd rather not do it yourself: Katman does this work on your site. Measurement, $99 once: whom the assistants recommend instead of you, whether bots can get into your site, which pages to write first. Implementation, $299 a month: we do the work in this book on your site; every change goes live after your approval. No ranking guarantee. katman.pro",
|
|
104
|
-
tr: "Kendiniz yapmak istemiyorsanız: sıfırdan açılan örnek sitemize ilk 7 günde ChatGPT’den 333 gerçek ziyaretçi getiren işi sizin sitenizde yapıyoruz. Ölçüm, 99 $ bir kez: asistanların yerinize kimi önerdiği, botların sitenize girip giremediği, önce hangi sayfaların yazılacağı. Uygulama, ayda 299 $: bu kitaptaki işleri sitenizde biz yapıyoruz; her değişiklik onayınızdan sonra yayına girer. Sıralama garantisi yok. katman.pro",
|
|
105
|
-
};
|
|
1
|
+
// Filled from katman.pro at run time for a paid key (see _store.js); the package carries no method text.
|
|
2
|
+
import { onMethod } from "./_store.js";
|
|
3
|
+
export let FIRST_30_DAYS = [];
|
|
4
|
+
export let PREPUBLISH_CHECKLIST = [];
|
|
5
|
+
export let ROADMAP_INTRO = {};
|
|
6
|
+
export let SAMPLE_NEXT = [];
|
|
7
|
+
onMethod((d) => {
|
|
8
|
+
if (d.FIRST_30_DAYS !== undefined) FIRST_30_DAYS = d.FIRST_30_DAYS;
|
|
9
|
+
if (d.PREPUBLISH_CHECKLIST !== undefined) PREPUBLISH_CHECKLIST = d.PREPUBLISH_CHECKLIST;
|
|
10
|
+
if (d.ROADMAP_INTRO !== undefined) ROADMAP_INTRO = d.ROADMAP_INTRO;
|
|
11
|
+
if (d.SAMPLE_NEXT !== undefined) SAMPLE_NEXT = d.SAMPLE_NEXT;
|
|
12
|
+
});
|
|
@@ -1,74 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
tr: "Tek sayfa uygulamalar (React, Vite ve benzerleri) sayfayı tarayıcıda çizer; sunucudan gelen HTML çoğu zaman boştur. Google JavaScript’i sonradan, bir kuyrukta çalıştırıyor ve yine de sunucu tarafı render’ı ya da ön-render’ı öneriyor. Araştırma notumuza göre ChatGPT’nin arama botu OAI-SearchBot JavaScript çalıştırmıyor. Örnek sitenin başlangıç sayfası botlara 27 kelime gösteriyordu; 86 kelimelik yazılı bir “Nasıl çalışır” bölümü ekledik.",
|
|
8
|
-
},
|
|
9
|
-
test: "curl -s {site_url}/ | sed 's/<[^>]*>/ /g' | wc -w",
|
|
10
|
-
testNote: { en: "If you get a few dozen words, your text is in JavaScript.", tr: "Birkaç düzine kelime çıkıyorsa metniniz JavaScript’te." },
|
|
11
|
-
fix: { en: "P2", tr: "P2" },
|
|
12
|
-
katman: "katman_audit_site → pages[].wordsJsOff; katman_scan_code → rendering.verdict",
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
n: 2,
|
|
16
|
-
title: { en: "AI bots are stuck at the door", tr: "Yapay zekâ botları kapıda kalıyor" },
|
|
17
|
-
text: {
|
|
18
|
-
en: "Even if your robots.txt is open, a CDN or firewall can turn bots away. We found this on our own site: our robots.txt allowed GPTBot while Cloudflare returned 403 to training bots; we switched it off. Cloudflare now has separate settings for training, search and agent bots, and the defaults changed for new domains. Details, the test command and the fix are in ch. 6.",
|
|
19
|
-
tr: "robots.txt’niz açık olsa bile CDN ya da güvenlik duvarı botları geri çevirebilir. Bunu kendi sitemizde bulduk: robots.txt’miz GPTBot’a izin verirken Cloudflare eğitim botlarına 403 veriyordu; kapattık. Cloudflare’de artık eğitim, arama ve ajan botları için ayrı ayarlar var ve yeni alan adlarında varsayılanlar değişti. Ayrıntısı, test komutu ve düzeltmesi 06. bölümde.",
|
|
20
|
-
},
|
|
21
|
-
test: "curl -s -o /dev/null -w \"%{http_code}\" -A \"GPTBot/1.2\" {site_url}/",
|
|
22
|
-
testNote: { en: "If it isn't 200, something is blocking.", tr: "200 değilse bir şey engelliyor." },
|
|
23
|
-
fix: { en: "Ch. 6 (CDN bot settings)", tr: "06. bölüm (CDN bot ayarları)" },
|
|
24
|
-
katman: "katman_audit_site → site.bots (status per AI user-agent)",
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
n: 3,
|
|
28
|
-
title: { en: "Soft 404s", tr: "Sahte 404’ler" },
|
|
29
|
-
text: {
|
|
30
|
-
en: "In a single-page app, a URL that doesn't exist returns the “page not found” screen with a 200 status code. Google counts this as a soft 404 and suggests two fixes: redirect to a URL that really returns 404, or add noindex to that screen.",
|
|
31
|
-
tr: "Tek sayfa uygulamada olmayan bir adres “sayfa bulunamadı” ekranını 200 durum koduyla döner. Google bunu sahte 404 (soft 404) sayar; iki çözüm öneriyor: gerçekten 404 dönen bir adrese yönlendirmek ya da o ekrana noindex eklemek.",
|
|
32
|
-
},
|
|
33
|
-
test: "curl -s -o /dev/null -w \"%{http_code}\" {site_url}/this-page-does-not-exist",
|
|
34
|
-
testNote: { en: "If it isn't 404, there's a problem.", tr: "404 değilse sorun var." },
|
|
35
|
-
fix: { en: "P11", tr: "P11" },
|
|
36
|
-
katman: "katman_audit_site → site.soft404",
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
n: 4,
|
|
40
|
-
title: { en: "An open preview copy", tr: "Açık kalmış önizleme kopyası" },
|
|
41
|
-
text: {
|
|
42
|
-
en: "Most hosts give every project a preview address (project.vercel.app and the like). If it stays open after you connect your real domain, Google sees two versions of the same site and picks the canonical itself — possibly the wrong one. Google uses an open demo copy as exactly this example; the fix is noindex, a password, or a redirect to the main address. robots.txt isn't enough.",
|
|
43
|
-
tr: "Çoğu barındırma servisi her projeye bir önizleme adresi verir (proje.vercel.app gibi). Asıl alan adını bağladıktan sonra o adres açık kalırsa Google aynı sitenin iki hâlini görür ve kanonik adresi kendisi seçer; yanlış olanı seçebilir. Google açık kalmış bir demo kopyasını tam olarak bu sorunun örneği olarak veriyor; çözüm noindex, şifre ya da asıl adrese yönlendirme. robots.txt yetmez.",
|
|
44
|
-
},
|
|
45
|
-
test: "Search Google for: site:vercel.app \"your brand\" (or your tool's preview domain: pages.dev, netlify.app, lovable.app …)",
|
|
46
|
-
testNote: { en: "Any result means the preview copy is indexable.", tr: "Sonuç çıkıyorsa önizleme kopyası dizine alınabiliyor." },
|
|
47
|
-
fix: { en: "P11", tr: "P11" },
|
|
48
|
-
katman: "katman_scan_code → hosting.previewPatterns; katman_audit_site preview-copy checks",
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
n: 5,
|
|
52
|
-
title: { en: "Links that aren't links", tr: "Linkler link değil" },
|
|
53
|
-
text: {
|
|
54
|
-
en: "A div that changes the page with onClick in a menu or a card isn't a link to a bot. Google only follows <a> tags with an href; URLs must change with real paths, not # fragments.",
|
|
55
|
-
tr: "Menüde ya da kartlarda onClick ile sayfa değiştiren bir div, bot için link değildir. Google yalnızca href’i olan <a> etiketlerini takip ediyor; adresler # parçasıyla değil, gerçek yollarla değişmeli.",
|
|
56
|
-
},
|
|
57
|
-
test: "curl -s {site_url}/ | grep -o '<a [^>]*href=\"/[^\"]*\"' | wc -l",
|
|
58
|
-
testNote: { en: "If it's lower than the number of pages in your menu, there's a problem.", tr: "Menüdeki sayfa sayısından azsa sorun var." },
|
|
59
|
-
fix: { en: "P10", tr: "P10" },
|
|
60
|
-
katman: "katman_scan_code → onClick navigation and hash routing findings",
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
n: 6,
|
|
64
|
-
title: { en: "Google yes, Bing and Brave no", tr: "Google var, Bing ve Brave yok" },
|
|
65
|
-
text: {
|
|
66
|
-
en: "Microsoft Copilot reads from Bing's index; per our research notes Claude uses Brave Search (medium confidence). Bing's guidelines count IndexNow, sitemaps and links for discovery, and ask you to send IndexNow as pages are added or changed. One detail from the sample site: on 24 September Bing had 0 of our pages while ChatGPT sent 40 people that day. Bing isn't required for ChatGPT; it is for Copilot.",
|
|
67
|
-
tr: "Microsoft Copilot Bing’in dizininden okuyor; araştırma notumuza göre Claude Brave Search’ü kullanıyor (orta güvenilirlikte bir bilgi). Bing’in yönergeleri keşif için IndexNow, sitemap ve linkleri sayıyor; IndexNow’u sayfa eklendikçe ve değiştikçe göndermenizi istiyor. Örnek sitede bir ayrıntı: 24 Eylül’de Bing’de 0 sayfamız varken ChatGPT o gün 40 kişi gönderdi. ChatGPT için Bing şart değil, Copilot için şart.",
|
|
68
|
-
},
|
|
69
|
-
test: "Search Bing (and search.brave.com) for: site:{domain}",
|
|
70
|
-
testNote: { en: "No results means those indexes don't have you yet.", tr: "Sonuç yoksa o dizinlerde henüz yoksunuz." },
|
|
71
|
-
fix: { en: "Ch. 13 (notify search engines; katman_indexnow)", tr: "13. bölüm (arama motorlarına bildirin; katman_indexnow)" },
|
|
72
|
-
katman: "katman_indexnow (IndexNow + the manual Google/Bing/Brave checklist)",
|
|
73
|
-
},
|
|
74
|
-
];
|
|
1
|
+
// Filled from katman.pro at run time for a paid key (see _store.js); the package carries no method text.
|
|
2
|
+
import { onMethod } from "./_store.js";
|
|
3
|
+
export let TRAPS = [];
|
|
4
|
+
onMethod((d) => {
|
|
5
|
+
if (d.TRAPS !== undefined) TRAPS = d.TRAPS;
|
|
6
|
+
});
|
|
@@ -1,88 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
n: 2,
|
|
16
|
-
title: { en: "Is a missing URL a real 404?", tr: "Olmayan adres gerçek 404 mü?" },
|
|
17
|
-
cmd: `curl -s -o /dev/null -w "%{http_code}\\n" {site_url}/this-page-does-not-exist`,
|
|
18
|
-
expect: { en: "404", tr: "404" },
|
|
19
|
-
katman: "katman_audit_site → site.soft404",
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
n: 3,
|
|
23
|
-
title: { en: "Title, description, canonical, robots, og:image", tr: "Title, açıklama, canonical, robots, og:image" },
|
|
24
|
-
cmd: `curl -s {site_url}/ | grep -o -i -E '<title>[^<]*|name="description" content="[^"]*|rel="canonical" href="[^"]*|name="robots" content="[^"]*|og:image" content="[^"]*'`,
|
|
25
|
-
expect: { en: "All five present; canonical is the page's own full URL; no unwanted noindex", tr: "Beşi de var; canonical sayfanın kendi tam adresi; istenmeyen noindex yok" },
|
|
26
|
-
katman: "katman_audit_site → title, description, canonicalSelf, noindex, ogImage",
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
n: 4,
|
|
30
|
-
title: { en: "How many words are visible without JavaScript?", tr: "JavaScript olmadan kaç kelime görünüyor?" },
|
|
31
|
-
cmd: `curl -s {site_url}/ | sed 's/<[^>]*>/ /g' | wc -w`,
|
|
32
|
-
expect: { en: "Hundreds, not a few dozen", tr: "Birkaç düzine değil, yüzlerce" },
|
|
33
|
-
katman: "katman_audit_site → pages[].wordsJsOff",
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
n: 5,
|
|
37
|
-
title: { en: "Can AI bots get in? (all should be 200)", tr: "Yapay zekâ botları içeri girebiliyor mu? (hepsi 200 olmalı)" },
|
|
38
|
-
cmd: `for b in GPTBot/1.2 OAI-SearchBot/1.0 ClaudeBot/1.0 PerplexityBot/1.0; do
|
|
39
|
-
echo "$b $(curl -s -o /dev/null -w '%{http_code}' -A "Mozilla/5.0 (compatible; $b)" {site_url}/)"; done`,
|
|
40
|
-
expect: { en: "200 for every bot", tr: "Her bot için 200" },
|
|
41
|
-
katman: "katman_audit_site → site.bots",
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
n: 6,
|
|
45
|
-
title: { en: "robots.txt and the sitemap", tr: "robots.txt ve sitemap" },
|
|
46
|
-
cmd: `curl -s {site_url}/robots.txt
|
|
47
|
-
curl -s {site_url}/sitemap.xml | grep -c "<loc>"`,
|
|
48
|
-
expect: { en: "No Disallow: /, a Sitemap line; the number of URLs you expect", tr: "Disallow: / yok, Sitemap satırı var; beklediğiniz sayıda adres" },
|
|
49
|
-
katman: "katman_audit_site → site.robots, site.sitemapUrls",
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
n: 7,
|
|
53
|
-
title: { en: "Is the page's JSON-LD valid JSON? (needs python3)", tr: "Sayfadaki JSON-LD geçerli JSON mu? (python3 gerekir)" },
|
|
54
|
-
cmd: `curl -s {site_url}/ | python3 -c "import sys,re,json; b=re.findall(r'<script[^>]*application/ld\\+json[^>]*>(.*?)</script>', sys.stdin.read(), re.S); [json.loads(x) for x in b]; print(len(b), 'valid JSON-LD blocks')"`,
|
|
55
|
-
expect: { en: "N valid JSON-LD blocks, no traceback", tr: "N geçerli JSON-LD bloğu, hata yok" },
|
|
56
|
-
katman: "katman_audit_site → pages[].jsonLdErrors",
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
n: 8,
|
|
60
|
-
title: { en: "Mobile speed and SEO score", tr: "Mobil hız ve SEO puanı" },
|
|
61
|
-
cmd: `npx lighthouse {site_url}/ --form-factor=mobile --only-categories=performance,seo --view`,
|
|
62
|
-
expect: { en: "LCP ≤ 2.5 s, CLS ≤ 0.1, SEO 100", tr: "LCP ≤ 2,5 sn, CLS ≤ 0,1, SEO 100" },
|
|
63
|
-
katman: "manual (Katman doesn't run Lighthouse)",
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
n: 9,
|
|
67
|
-
title: { en: "Is the HTML compressed? (re-check after every technical fix)", tr: "HTML sıkıştırılıyor mu? (her teknik düzeltmeden sonra tekrar)" },
|
|
68
|
-
cmd: `curl -s -o /dev/null -D - -H 'Accept-Encoding: br, gzip' {site_url}/ | grep -i content-encoding`,
|
|
69
|
-
expect: { en: "content-encoding: br (or gzip)", tr: "content-encoding: br (ya da gzip)" },
|
|
70
|
-
katman: "katman_audit_site → site.compression",
|
|
71
|
-
},
|
|
72
|
-
];
|
|
73
|
-
export const BROWSER_CHECKS = [
|
|
74
|
-
{
|
|
75
|
-
en: "Search Console → URL Inspection → Test live URL → View tested page: the HTML and screenshot Google sees. If your text isn't there, it isn't in Google either.",
|
|
76
|
-
tr: "Search Console → URL denetimi → Canlı URL’yi test et → Taranan sayfayı görüntüle: Google’ın gördüğü HTML ve ekran görüntüsü. Metniniz burada yoksa Google’da da yok.",
|
|
77
|
-
},
|
|
78
|
-
{ en: "Rich Results Test (search.google.com/test/rich-results): JSON-LD errors.", tr: "Zengin Sonuçlar Testi (search.google.com/test/rich-results): JSON-LD hataları." },
|
|
79
|
-
{
|
|
80
|
-
en: "Chrome → Developer tools → Settings → Disable JavaScript: see the page through the bot's eyes.",
|
|
81
|
-
tr: "Chrome → Geliştirici araçları → Ayarlar → JavaScript’i devre dışı bırak: sayfayı botun gözüyle görün.",
|
|
82
|
-
},
|
|
83
|
-
{ en: "Paste a link into a chat app: does the og:image card appear?", tr: "Bir sohbet uygulamasına link yapıştırın: og:image kartı çıkıyor mu?" },
|
|
84
|
-
];
|
|
85
|
-
export const VERIFY_EXERCISE = {
|
|
86
|
-
en: "Run the nine commands on your home page and on your most important situation page. Paste the output into research; run them again in 30 days and compare.",
|
|
87
|
-
tr: "Dokuz komutu kendi sitenizin ana sayfasında ve en önemli durum sayfanızda çalıştırın. Çıktıları research.md’ye yapıştırın; 30 gün sonra tekrar çalıştırıp karşılaştırın.",
|
|
88
|
-
};
|
|
1
|
+
// Filled from katman.pro at run time for a paid key (see _store.js); the package carries no method text.
|
|
2
|
+
import { onMethod } from "./_store.js";
|
|
3
|
+
export let BROWSER_CHECKS = [];
|
|
4
|
+
export let NINE_COMMANDS = [];
|
|
5
|
+
export let VERIFY_EXERCISE = {};
|
|
6
|
+
export let VERIFY_INTRO = {};
|
|
7
|
+
onMethod((d) => {
|
|
8
|
+
if (d.BROWSER_CHECKS !== undefined) BROWSER_CHECKS = d.BROWSER_CHECKS;
|
|
9
|
+
if (d.NINE_COMMANDS !== undefined) NINE_COMMANDS = d.NINE_COMMANDS;
|
|
10
|
+
if (d.VERIFY_EXERCISE !== undefined) VERIFY_EXERCISE = d.VERIFY_EXERCISE;
|
|
11
|
+
if (d.VERIFY_INTRO !== undefined) VERIFY_INTRO = d.VERIFY_INTRO;
|
|
12
|
+
});
|