2021 में वापस, एक ट्रैवल क्लाइंट ने Seahawk को एक माइग्रेशन ब्रीफ दिया जिसने मेरा पेट हल्का कर दिया। इक्यानवे हजार डेस्टिनेशन और होटल पेज। हर एक को वैलिड, स्पेसिफिक, टेस्टेड स्कीमा मार्कअप की जरूरत थी, न कि वह आलसी वन-साइज़-फिट्स-ऑल WebPage टाइप जो ज्यादातर प्लगइन लगाते हैं और बस इतना कहते हैं। क्लाइंट ने पहले से ही दो "ऑटोमैटिक स्कीमा" WordPress प्लगइन आजमा चुके थे। दोनों ने तकनीकी रूप से वैलिड JSON-LD प्रोड्यूस किया था जो हर मायने में बेकार भी था, जेनेरिक नाम, कोई नेस्टेड एंटिटीज नहीं, प्राइसेस मिसिंग, रिव्यू एग्रीगेट्स गलत चीज़ की ओर पॉइंट कर रहे थे। Google का Rich Results Test शालीनता से भ्रमित था।
मुख्य निष्कर्ष: 91,000 पृष्ठों के लिए स्कीमा एक आर्किटेक्चर समस्या है, प्लगइन समस्या नहीं: इसे बिल्ड टाइम पर डेटा लेयर से जेनरेट करें और पाइपलाइन में वैलिडेट करें।
उस प्रोजेक्ट ने मुझे पिछले आठ सालों की तुलना में स्केल पर स्कीमा के बारे में कहीं अधिक सिखाया। तो यहाँ है जो मुझे वास्तव में पता है।
---
"बस एक प्लगइन इंस्टॉल करो" स्केल पर क्यों टूट जाता है
देखिए, मैं यहाँ Yoast या Rank Math पर तनक़ी करने नहीं आया हूँ। 40-पेज की ब्रोशर साइट के लिए वे वाक़ई ठीक हैं। लेकिन 500-पेज के आसपास कहीं, प्लगइन-जेनरेटेड स्कीमा अपनी ख़ुद की मान्यताओं के तहत टूटने लगता है।
मूल समस्या यह है कि प्लगइन पेज टेम्पलेट के चारों ओर बनाए जाते हैं, डेटा मॉडल के नहीं। वे पोस्ट टाइटल को पढ़ते हैं, शायद एक-दो कस्टम फील्ड, और एक स्कीमा ब्लॉब बनाते हैं। जब आपके साइट पर 91,000 पेज छह कंटेंट टाइप में फैले हुए हों—होटल, डेस्टिनेशन, टूर, रिव्यू, FAQ, और ऑथर प्रोफाइल—एक सिंगल प्लगइन कॉन्फ़िगरेशन उस विविधता को विशाल मैनुअल ओवरराइड काम के बिना एक्सप्रेस नहीं कर सकता। और अगर आप उस स्केल पर मैनुअल ओवरराइड कर रहे हैं, तो आप पहले ही हार चुके हैं।
बात यह है: स्कीमा मार्कअप मौलिक रूप से एक डेटा ट्रांसफॉर्मेशन समस्या है। आपके पास डेटाबेस में संरचित डेटा है; आपको इसे एक <script> टैग में JSON-LD के रूप में व्यक्त करने की जरूरत है। बस इतना ही। जिस क्षण आप इसे इस तरीके से समझते हैं, सही आर्किटेक्चर बहुत स्पष्ट हो जाता है।
तीन विफलता मोड जो मैं लगातार देख रहा हूँ
- स्टैटिक स्कीमा ब्लॉब्स टेम्पलेट्स में हार्डकोड किए गए। ठीक है जब तक प्रोडक्ट का नाम न बदले, फिर आपके पास 12,000 पेजेज़ Google को झूठ बोल रहे हैं।
- प्लगइन कॉन्फ़िग जो कंडीशनल लॉजिक को हैंडल नहीं कर सकते, जैसे aggregateRating को केवल तभी दिखाना जब वास्तव में रिव्यू हों, या पोस्ट कैटेगरी के अनुसार अलग @type।
- बैच-जेनरेटेड फाइलें एक बार अपलोड कीं और कभी अपडेट नहीं कीं। मैंने साइट्स ऑडिट किए हैं जहाँ स्कीमा अठारह महीने पुरानी थी। कीमतें गलत थीं। इवेंट के डेट्स पास हो चुके थे।
---
JSON-LD वास्तव में बड़े पैमाने पर कैसे काम करता है
टूलिंग में जाने से पहले: एक त्वरित आधार। JSON-LD, JSON for Linked Data, Google का पसंदीदा स्कीमा फॉर्मेट है क्योंकि यह एक <script> ब्लॉक में रहता है, आपके HTML से अलग। मतलब आप इसे सर्वर-साइड जेनरेट कर सकते हैं, इसे साफ-सुथरे तरीके से इंजेक्ट कर सकते हैं, और मार्कअप को छुए बिना इसे अपडेट कर सकते हैं। वह सेपरेशन सब कुछ है जब आप हजारों पेजों से निपट रहे हों।
Schema.org शब्दावली विशाल है। ज्यादातर लोग इसके 1% का उपयोग करते हैं। स्केल पर आपको गहराई में जाना होगा: Hotel, TouristDestination, LocalBusiness, Review, AggregateRating, नेस्टेड Offer ऑब्जेक्ट, BreadcrumbList। हर टाइप के पास रिक्वायर्ड और रिकमेंडेड प्रॉपर्टीज होती हैं, और Google की "रिकमेंडेड" की व्याख्या मूलतः "रिक्वायर्ड इफ यू वांट द रिच रिजल्ट" है।
वह फंडामेंटल रूल जिसे मैं फॉलो करता हूँ: एक प्राइमरी `@type` प्रति पेज, नेस्टेड टाइप्स ज़रूरत के हिसाब से। पाँच @type वैल्यूज़ स्टैक करने की कोशिश न करें यह उम्मीद में कि एक स्टिक हो जाए। सबसे स्पेसिफ़िक टाइप चुनें जो फ़िट हो, फिर सपोर्टिंग टाइप्स इसके अंदर नेस्ट करें।
---
आर्किटेक्चर जो हमने असल में इस्तेमाल किया
ट्रैवल क्लायंट के लिए, हम तीन-लेयर सिस्टम पर पहुँचे। व्हाइटबोर्ड-डायग्राम के नजरिये से सुंदर नहीं, लेकिन यह काम करता था।
लेयर 1: टेम्पलेट-स्तरीय Schema क्लासेज़ (PHP)
हर कंटेंट टाइप को अपना PHP क्लास मिला जो अपने स्कीमा एरे को बिल्ड करने के लिए जिम्मेदार था। HotelSchemaBuilder, DestinationSchemaBuilder, TourSchemaBuilder, आप समझ गए। हर क्लास ACF Pro कस्टम फील्ड से खींचता था, जहां लागू हो WooCommerce डेटा, और कुछ कंप्यूटेड वैल्यूज़ (जैसे CPT-बेस्ड रिव्यू सिस्टम से aggregateRating कैलकुलेट करना)।
हर क्लास का आउटपुट एक साधारण PHP ऐरे था। अभी JSON नहीं। बस डेटा।
यह ज़रूरी है क्योंकि इसका मतलब है कि आप डेटा लॉजिक को सीरिएलाइज़ेशन से अलग यूनिट टेस्ट कर सकते हैं। मुझे शुरू से ही इस प्रोजेक्ट पर ऐसा करना चाहिए था। मैंने नहीं किया। इसकी कीमत हमें स्टेजिंग में करीब दो दिन की डिबगिंग में पड़ी जब ratingValue एक स्ट्रिंग की जगह फ़्लोट रिटर्न कर रहा था और Google का वैलिडेटर चुपचाप पूरे aggregateRating ब्लॉक को इग्नोर कर रहा था।
लेयर 2: एक सेंट्रल Schema Manager
एक सिंगल SchemaManager क्लास, wp_head में हुक किया गया, इसके लिए ज़िम्मेदार था:
- वर्तमान टेम्पलेट/पोस्ट टाइप के आधार पर कौन सा बिल्डर क्लास invoke करना है, यह निर्धारित करना
- साइटव्यापी entities को मर्ज करना (Organization graph, WebSite with SearchAction, BreadcrumbList)
- JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE के साथ अंतिम array को JSON के रूप में encode करना
- इसे <script type="application/ld+json"> टैग में wrap करना और echo करना
breadcrumb logic सबसे मुश्किल हिस्सा था। Destinations के पास तीन-स्तरीय hierarchy था: Region → Country → City। BreadcrumbList को गतिशील रूप से प्रतिबिंबित करना, कुछ भी hardcode किए बिना, इसका अर्थ था render time पर post ancestors को traverse करना। यदि आप सावधान न हों तो धीमा। हमने breadcrumb arrays को post ID के per एक transient में cache किया 24-hour TTL के साथ। इससे overhead को नगण्य तक नीचे लाया गया।
Layer 3: Validation और Monitoring
Schema generate करना पहला कदम है। जानना कि यह कब टूटता है, दूसरा कदम है, और ज्यादातर teams इसे पूरी तरह skip कर देती हैं।
हमने एक Google Search Console प्रॉपर्टी सेटअप की और साप्ताहिक रूप से Rich Results रिपोर्ट देखी। लेकिन यह रिएक्टिव है, GSC आपको Google के क्रॉल करने के बाद एरर के बारे में बताता है। प्रोएक्टिव चेक के लिए, हमने महीने में एक बार 2,000 टॉप पेजों की क्रॉल पर SchemaApp चलाया। यह प्रॉपर्टी-लेवल एरर्स सर्फेस करता है जो GSC रिपोर्ट छुपाती है।
साथ ही: Google के Rich Results Test के पास एक API है। हमने एक छोटी script लिखी जो हर रात 50 URLs के एक random sample के साथ API को hit करेगी और किसी भी validation failures को log करेगी। सस्ता बीमा।
---
गतिशील डेटा को संभालना — परफॉर्मेंस को बर्बाद किए बिना
यहाँ वह जगह है जहाँ ज्यादातर स्केल इम्प्लीमेंटेशन गिरते हैं। स्कीमा जो लाइव डेटा, प्राइसिंग, एवेलेबिलिटी, रिव्यू काउंट्स को रेफर करता है, को ताज़ा रहना होता है। लेकिन 91,000 पेजों में से हर एक पेज लोड पर JSON-LD रीजेनरेट करना मुफ़्त नहीं है।
मेरा तरीका, और मैंने इसे शायद एक दर्जन बड़ी साइटों पर रिफाइन किया है:
आक्रामक तरीके से कैश करें, स्मार्ट तरीके से इनवेलिडेट करें।
होटल पेजेस के लिए, स्कीमा ब्लॉब को पोस्ट मेटा के रूप में स्टोर किया जाता था — एक सीरियलाइज़्ड JSON-LD स्ट्रिंग — और केवल तभी रीजनरेट किया जाता था:
- पोस्ट खुद अपडेट होती है
- उस पोस्ट के लिए एक नया रिव्यू सबमिट होता है
- price custom field बदला गया (हमने इसके लिए ACF save_post action में hook किया)
बाकी सब कुछ कैश्ड स्ट्रिंग से सर्व किया जाता है। बिलकुल तेज़। और क्योंकि इनवेलिडेशन हुक्स विशिष्ट थे, स्कीमा सटीक रहता था।
एक चीज़ जो मैंने शुरुआत में गलत की: मैंने पूरे <script> tag को cache किया, opening और closing elements सहित। फिर हमें एक content type के लिए @context URL बदलने की जरूरत थी। हर cache entry को bust करना पड़ा। अब मैं केवल JSON string को cache करता हूँ और render time पर इसे wrap करता हूँ। पाँच मिनट की अतिरिक्त code, एक घंटे की head-scratching को बचाया।
असल कीमतों के बारे में क्या?
tour pricing के लिए जो दिन में कई बार बदलता था, हमने एक अलग approach लिया। base schema को cache किया गया था, लेकिन Offer block को request time पर fresh generate किया गया था और serialisation से पहले merge किया गया था। हाँ, इसने प्रति request एक छोटा overhead जोड़ा। लेकिन यह page load के per एक database query था, बारह नहीं। स्वीकार्य trade-off।
---
कई साइटों तक स्केल करना: Seahawk का कोण
Seahawk ने 12,000 से अधिक साइटें बनाई हैं, और स्कीमा इम्प्लीमेंटेशन उनके काफ़ी हिस्से में आता है। ट्रैवल क्लाइंट एक सीमांत मामला था। लेकिन वही आर्किटेक्चरल सिद्धांत चाहे आप 91,000 पेजेज़ पर काम कर रहे हों या 4,000 पर, लागू होते हैं।
जो पैटर्न मैंने एक रीयूजेबल सॉल्यूशन के रूप में अपनाया है वह एक छोटा इंटरनल WordPress प्लगइन है, जिसे हम seahawk-schema-core कहते हैं, जो मैनेजर/बिल्डर स्कैफोल्डिंग प्रदान करता है लेकिन किसी भी कंटेंट-टाइप-स्पेसिफिक लॉजिक के बिना। क्लाइंट प्रोजेक्ट्स इसे अपनी खुद की बिल्डर क्लासेस के साथ एक्सटेंड करते हैं। कोर स्कीमा लॉजिक के लिए कोई प्लगइन डिपेंडेंसीज नहीं। कोई रिस्क नहीं कि किसी थर्ड-पार्टी प्लगइन का अपडेट किसी साइट की संपूर्ण रिच रिजल्ट्स प्रेजेंस को तोड़ दे।
वह आखिरी बात वास्तविकता में लोग जितना स्वीकार करते हैं उससे ज्यादा असली है। मैंने देखा है कि Rank Math के अपडेट्स कस्टम स्कीमा ओवरराइड्स को चुप्पे से तोड़ देते हैं। इसलिए नहीं कि Rank Math बुरा है, यह नहीं है, बल्कि इसलिए कि जब आप उस लेवल पर आउटपुट को कस्टमाइज़ कर रहे होते हैं जिसकी एक बड़ी साइट को जरूरत है, तो आप उस चीज़ के बाहर काम कर रहे होते हैं जिसके लिए प्लगइन डिज़ाइन किया गया था। कोड पर मालिकाना, रिस्क प्रोफाइल पर मालिकाना।
---
इस स्केल पर टेस्टिंग: एक व्यावहारिक चेकलिस्ट
आप 91,000 URLs को मैन्युअली टेस्ट नहीं कर सकते। तो आप स्मार्टली टेस्ट करते हैं।
- टेम्पलेट टाइप के हिसाब से सैंपल लें। हर कंटेंट टाइप से 10 URLs पिक करें। उन्हें टेस्ट करें। अगर बिल्डर एक होटल पेज के लिए सही है, तो यह 3,000 होटल पेजेस सभी के लिए सही है (जब तक कि कोई ख़राब डेटा न हो, उस पर आगे चर्चा)।
- विशेष रूप से edge cases को टेस्ट करें। कोई रिव्यू न होने वाले पेज। अधूरे कस्टम फील्ड वाले पेज। टाइटल में स्पेशल कैरेक्टर वाले पेज (&, ", एक्सेंटेड कैरेक्टर)। JSON सीरिएलाइजेशन इनमें से ज्यादातर को खा जाता है, लेकिन सभी को नहीं।
- Screaming Frog के साथ एक पूर्ण structured data crawl चलाएँ। Screaming Frog SEO Spider के पास एक structured data extraction mode है जो हर URL से JSON-LD को pull और validate करेगा जिसे यह crawl करता है। errors को export करें, template type के आधार पर group करें, source पर fix करें।
- GSC के Enhancements टैब को मॉनिटर करें। एक थ्रेशहोल्ड अलर्ट सेट करें — अगर वैलिड आइटम्स हफ़्ते-दर-हफ़्ते 5% से ज्यादा गिरते हैं, तो कुछ टूटा है। 48 घंटों के भीतर एक्शन लें।
- हर डिप्लॉयमेंट के बाद स्पॉट-चेक करें। भले ही स्कीमा कोड न बदला हो। डेटाबेस माइग्रेशन्स, प्लगइन अपडेट्स, थीम चेंजेस — इनमें से कोई भी अपस्ट्रीम डेटा इश्यूज introduce कर सकता है जो स्कीमा आउटपुट को corrupt करते हैं।
बुरा डेटा साइलेंट किलर है
ट्रैवल साइट के पास तीन देशों में बारह लोगों की एक कंटेंट टीम थी। कुछ डेस्टिनेशन पेजेस में डेस्क्रिप्शन फील्ड में ख़राब HTML था, presumably Word से पेस्ट किया गया। जब वह फील्ड स्कीमा डेस्क्रिप्शन प्रॉपर्टी में फीड होता था, तो JSON technically valid था लेकिन डेस्क्रिप्शन में entities और stray <span> tags शामिल थे। Google ने प्रॉपर्टी को ignore किया। हमने हर बिल्डर क्लास में एक सैनिटाइज़ेशन स्टेप जोड़ा जो स्कीमा array में आने से पहले टैग्स को strip करता है और HTML entities को decode करता है। इसे permanently हल कर दिया।
---
द एंटिटी ग्राफ: इसे ignore न करें
एक चीज़ जो mediocre स्कीमा वर्क को genuinely अच्छे technical SEO से अलग करती है वह entity graph है, specifically, sitewide Organization और WebSite entities जो हर पेज पर दिखने चाहिए और सब कुछ को एक साथ लिंक करना चाहिए।
ज़्यादातर साइटों के पास ये हैं, लेकिन ख़राबी से। Name, URL, शायद एक logo। पूरा Organization type sameAs links को आपकी Wikidata entry में, social profiles में, और अन्य authoritative sources को सपोर्ट करता है। वह cross-linking यह है कि Google को confidence मिलता है कि आपकी Organization entity उसके Knowledge Graph में वही entity है जो आपके page schema में दिख रही है।
उस ट्रैवल क्लाइंट के लिए, हमने Organization block को इसके साथ बनाया:
- sameAs जो उनकी Crunchbase profile, LinkedIn page, और एक Wikipedia stub को point करता है जो उनके पास था
- contactPoint structured phone और department info के साथ
- foundingDate और numberOfEmployees (rough range, यह anyway public info है)
क्या इसने रात भर रैंकिंग को हिलाया? नहीं। स्कीमा अलगाव में लगभग कभी नहीं करता। लेकिन यह ढांचा है। आप इसे एक बार ठीक से बनाते हैं, और यह समय के साथ चक्रवृद्धि होता है।
---
FAQ
इस पैमाने पर स्कीमा को लागू करने में कितना समय लगता है?
91,000-पेज वाली ट्रैवल साइट के लिए, complete implementation, architecture, बिल्डर क्लासेस, caching layer, testing, GSC monitoring setup, दो developers के साथ लगभग छह हफ़्ते लगे। यह काफी लगता है। लेकिन उस समय का आधा part existing data quality को audit करने में गया था, स्कीमा कोड लिखने में नहीं। अगर आपका डेटा clean है, तो आप तेजी से आगे बढ़ सकते हैं।
क्या मुझे बड़ी साइटों के लिए प्लगइन का उपयोग करना चाहिए या कस्टम बनाना चाहिए?
कुछ सौ पेजों तक कुछ भी हो, प्लगइन वाकई ठीक है। Rank Math का schema मॉड्यूल ठोस है और कस्टम schema ब्लॉक आपको सकारण लचीलापन देता है। कई हज़ार पेजों से ऊपर जहाँ कई अलग कंटेंट टाइप हों, मैं हर बार कस्टम बनाता हूँ। कंट्रोल बिल्ड कॉस्ट के लायक है।
बड़े स्तर पर schema का सबसे आम गलती क्या है?
जब reviews मौजूद हों तो aggregateRating miss करना, या जब न हों तो include करना — दोनों गलत हैं। Google इस पर कड़ा है। अगर आपका schema 843 reviews से 4.7 की aggregateRating claim करता है और user page पर आता है तो कोई reviews नहीं दिखते, तो manual action सीधे आने वाली है। आपके builder classes में conditional logic non-negotiable है।
क्या schema सीधे रैंकिंग में सुधार करता है?
सीधे तौर पर? ज़्यादातर query types के लिए शायद ज़्यादा कुछ नहीं। जो करता है वह है rich results, star ratings, FAQ dropdowns, review snippets, breadcrumbs SERP में unlock करना — और ये features click-through rates को measurably improve करते हैं। मेरे travel client को hotel pages पर full implementation के चार महीने में 22% CTR increase दिखा। यह engagement signals में feed होता है, जो rankings को affect करते हैं। तो: indirectly, हाँ। Substantially।
आप schema काम के लिए रोज़-मर्रा कौन से टूल्स इस्तेमाल करते हैं?
Crawl-level auditing के लिए Screaming Frog। Spot-checks के लिए Google का Rich Results Test। Property-level validation के लिए Schema Markup Validator at validator.schema.org। और ईमानदारी से कहूँ तो Schema.org documentation ही — मेरे पास Hotel type page और कुछ दूसरे bookmarked हैं और मैं उन्हें constantly refer करता हूँ। कोई fancy subscription tool की ज़रूरत नहीं।
---
बड़े स्तर पर Schema उन समस्याओं में से एक है जो प्लगइन समस्या की तरह दिखती है जब तक कि आप अंदर न हों और यह समझ न जाएँ कि यह वाकई एक सॉफ्टवेयर आर्किटेक्चर समस्या है जिसे SEO कपड़ों में पहनाया गया है। डेटा मॉडल को सही करो। बुद्धिमानी से कैश करो। निरंतर वैलिडेट करो। markup खुद लगभग आसान हिस्सा है।
