SEO

React- ja Next.js-lehe SEO: mis päriselt loeb

„React on SEO-le halb" on üks visadamaid veebiarenduse müüte. Selles on tõetera, aga see puudutab üht kindlat viisi Reacti kasutada — mitte Reacti ennast.

Kui sul on React- või Next.js-leht või kaalud sellist, on sisuliselt kaks küsimust. Kas otsingumootor näeb lehe sisu ilma JavaScripti käivitamata? Ja kas leht on tehniliselt korras nagu iga teine hästi tehtud koduleht? Esimene on arhitektuuri küsimus, teine kontroll-loendi oma.

Kust müüt pärit on

Klassikaline React-rakendus (SPA, single-page application) saadab serverist peaaegu tühja HTML-i: üks <div> ja viide skriptifailile. Kogu sisu — pealkirjad, tekstid, lingid — tekib alles siis, kui brauser on JavaScripti alla laadinud ja käivitanud.

Inimese jaoks vahet ei ole, ta näeb valmis lehte. Roomaja jaoks on.

Google renderdab JavaScripti küll, aga eraldi etapis. Esmalt loeb ta HTML-i, renderdamine toimub hiljem, kui selleks ressurssi jagub. Enamasti see õnnestub. Aga kui skript annab vea, andmepäring aegub või mõni fail on robots.txt-iga blokeeritud, indekseerib Google selle, mis HTML-is oli — ehk mitte midagi.

Paljud teised ei renderda üldse. Suur osa muudest roomajatest, tehisintellekti-teenuste robotid ja lingieelvaated (Facebook, LinkedIn, Slack, WhatsApp) loevad ainult toorest HTML-i. Kliendipoolselt renderdatud leht on nende jaoks tühi: jagatud lingil pole pealkirja ega pilti ja AI-otsingul pole millestki tsiteerida.

Probleem ei ole seega React, vaid see, kus HTML valmib.

Lahendus: HTML valmib serveris või ehitamise ajal

Kaks viisi, mis mõlemad annavad roomajale kohe valmis sisu:

  • Serveripoolne renderdamine (SSR) — server koostab HTML-i iga päringu peale.
  • Staatiline genereerimine (SSG) — HTML koostatakse ette, ehitamise (build) ajal, ja server lihtsalt saadab valmis faili.

Next.js teeb seda vaikimisi. App Routeris on komponendid serverikomponendid ja leht genereeritakse staatiliseks, kui see ei vaja päringupõhiseid andmeid. Iga URL tagastab päris HTML-i koos sisuga; JavaScript lisab peale ainult interaktiivsuse (seda nimetatakse hüdratsiooniks).

Kiirtest: kas tekst on HTML-is?

Ava leht, vajuta Ctrl+U (Macis Cmd+Option+U) ja otsi lehelt mõnda lauset. Mitte arendajatööriistade kaudu — need näitavad lehte juba pärast JavaScripti. Sama käsurealt:

curl -s https://sinu-leht.ee/teenused/ | grep -c "lause, mis on lehel näha"

Kui tulemus on 0, sünnib sisu alles brauseris. Search Console'i URL-i kontrolli tööriist näitab lisaks, millise HTML-i Google pärast renderdamist sai.

Kontroll-loend React- ja Next.js-lehele

Serveripoolne HTML on eeldus, mitte kogu töö. Järgmine on see, mis peab igal lehel paigas olema.

Igal lehel oma title ja meta-kirjeldus. SPA-de sagedaseim viga: sama pealkiri igal URL-il. Next.js-is määrab selle metadata eksport või dünaamilistel lehtedel generateMetadata, ja see jõuab HTML-i <head>-i juba serveris, mitte hiljem.

Canonical. Iga leht ütleb, milline URL on tema ametlik aadress — muidu võivad päringuparameetrite ja kaldkriipsuga variandid võistelda sama lehe duplikaatidena.

hreflang mitmekeelsel lehel. Iga keeleversioon viitab kõigile teistele ja x-default-ile ning viited peavad olema vastastikused. Meie enda lehel on viis keelt tõlgitud URL-idega ja iga leht saab canonicali ning hreflangid ühest kohast — käsitsi ei püsiks see viie keele peale õigena.

Genereeritud sitemap.xml ja robots.txt. Next.js-is on need failid app/sitemap.ts ja app/robots.ts. Sitemap tekib samast andmestikust mis lehed, seega uus leht ei saa sealt välja ununeda. Meie sait genereerib sitemapi ehitamise ajal.

Struktureeritud andmed (JSON-LD). Ettevõte, teenused, artiklid, KKK ja leivapururada <script type="application/ld+json"> plokis. See peab olema algses HTML-is, mitte kliendi poolt hiljem lisatud.

Päris lingid. Google järgib <a href> linke, nuppudel ta ei kliki. Next.js-i Link renderdab korraliku <a>-elemendi. Navigeerimine, mis toimub ainult onClick-i ja router.push() kaudu, on roomaja jaoks nähtamatu.

Päris 404. Puuduv leht peab andma HTTP koodi 404, mitte 200 koos tekstiga „lehte ei leitud" — viimast nimetab Google pehmeks 404-ks (soft 404). Next.js-is teeb seda notFound(). Staatilise ekspordi puhul peab majutus serveerima 404-lehte õige koodiga.

Üks kaldkriipsu reegel. /teenused ja /teenused/ on kaks eri URL-i. Vali üks (Next.js-is trailingSlash), suuna teine 301-ga ümber ja jälgi, et siselingid kasutaksid sama kuju. Kui uus leht asendab vana, vaata ka, kuidas uuendada kodulehte positsioone kaotamata.

Pildid mõõtude ja alt-tekstiga. width ja height hoiavad ruumi ette kinni, nii et sisu ei hüppa (CLS). next/image nõuab neid niikuinii. Staatilises ekspordis on Next.js-i automaatne pildioptimeerimine välja lülitatud — pildid tuleb enne ise mõistlikku mõõtu pakkida.

Kliendikomponendid ainult sinna, kus on interaktsioon. 'use client' saadab komponendi koos kõigi tema importidega brauserisse. Menüü, vorm ja filter vajavad seda; tekstiplokk ja jalus mitte.

Kiirus: Reacti-spetsiifilised lõksud

Core Web Vitals'i üldpilt on lahti kirjutatud artiklis kodulehe kiirus: kuidas seda mõõta ja parandada. React-lehel on lisaks kolm oma lõksu.

JavaScripti maht ja hüdratsioon

Ka serveris renderdatud leht laeb JavaScripti alla ja hüdreerib end. Kuni see pole lõppenud, ei reageeri nupud — see mõjutab INP-d, eriti odavamal telefonil. Iga kliendikomponent ja iga teek (karussell, animatsiooniteek, kuupäevateek) suurendab paketti. Raske vidin lehe allosas tasub laadida alles siis, kui seda vaja on (next/dynamic).

Ära peida pealkirja JavaScripti taha

Levinud muster: sisu „ilmub" sujuvalt ja on selleks algul opacity: 0, kuni skript annab loa nähtavaks muutuda. Kui nii tehakse lehe põhipealkirjaga, ootab LCP — Google'i peamine laadimiskiiruse näitaja — ära JavaScripti allalaadimise ja hüdratsiooni. Kui skript ei laadi, jääbki pealkiri nähtamatuks.

Õppisime seda oma lehel. Avalehe pealkiri on LCP-element ja kasutab nüüd puhast CSS-animatsiooni, mis käivitub esimesest maalimisest, mitte JavaScripti-põhist ilmumist. Kerimisel ilmuvad efektid allpool on eraldi asi — pealkiri neist ei sõltu.

Ära saada brauserisse kõiki keeli

Mitmekeelsel lehel on lihtne kogemata importida kliendikomponenti terve tõlkesõnastik. Siis laeb iga külastaja alla kõigi keelte tekstid. Parem muster: serverikomponent loeb teksti ja annab kliendikomponendile propsidena ainult need stringid, mida see vajab.

Staatiline eksport: iga leht on valmis fail

Next.js suudab kogu saidi eksportida puhtaks HTML-iks (output: 'export'). Tulemus on kaust faile, mida serveerib ükskõik milline veebiserver või CDN.

  • Kiire — külastuse hetkel ei arvuta server midagi.
  • Turvaline — andmebaasi, halduspaneeli ega serverikoodi, mida rünnata, ei ole.
  • Odav majutada — piisab tavalisest staatilisest majutusest.

Meie oma sait on täielikult staatiline eksport: Next.js (App Router), React ja TypeScript, viis keelt.

Hind selle eest: iga sisumuudatus tähendab uut ehitamist ja üleslaadimist. Ettevõtte kodulehele ja blogile, mis muutub kord nädalas, sobib see hästi. Kui sisu muutub iga minut, kasutajatel on kontod või on vaja otsingut andmebaasist, vajad serveripoolset renderdamist või eraldi teenust. Ka kontaktivorm vajab väikest serveripoolset vastuvõtjat.

Kui oled praegu WordPressis ja kaalud üleminekut, loe WordPressilt üleminek ilma SEO-d kaotamata ja üldisemat võrdlust WordPress vs koodipõhine koduleht.

Millal abi kutsuda

Kui sul on juba React-leht, tee kolm kontrolli: vaata kolme lehe lähtekoodi, võrdle Search Console'is indekseeritud lehtede arvu tegeliku lehtede arvuga ja vaata, kas pealkirjad lehtede vahel erinevad. Kui tekst HTML-ist puudub, ei aita meta-siltide kohendamine — renderdamine tuleb ümber korraldada, sageli SPA-lt Next.js-ile üle minnes.

Ehitame kodulehti Next.js-iga nii, et kõik ülaltoodu on algusest peale sees. Kui leht on olemas, aga Google'is ei liigu, alusta SEO-optimeerimisest.

Loe veel

Seotud teenused

Valmis viima oma äri uuele tasemele?

Võta meiega ühendust juba täna ja teeme koos midagi erakordset.

Võta ühendust