SEO

React- ja Next.js-sivuston hakukoneoptimointi

”React on huono hakukoneoptimoinnille” on yksi web-kehityksen sitkeimmistä myyteistä. Siinä on totuuden siemen, mutta se koskee yhtä tiettyä tapaa käyttää Reactia — ei Reactia itseään.

Jos sinulla on React- tai Next.js-sivusto tai harkitset sellaista, React-sivuston hakukoneoptimoinnissa on oikeastaan kaksi kysymystä. Näkeekö hakukone sivun sisällön ajamatta JavaScriptiä? Ja onko sivusto teknisesti kunnossa kuten mikä tahansa hyvin tehty sivusto? Ensimmäinen on arkkitehtuurikysymys, toinen tarkistuslistan asia.

Mistä myytti on peräisin

Perinteinen React-sovellus (SPA, single-page application) lähettää palvelimelta lähes tyhjän HTML:n: yhden <div>-elementin ja viittauksen skriptitiedostoon. Kaikki sisältö — otsikot, tekstit, linkit — syntyy vasta, kun selain on ladannut ja ajanut JavaScriptin.

Ihmiselle sillä ei ole väliä, hän näkee valmiin sivun. Hakurobotille on.

Google renderöi JavaScriptiä, mutta erillisessä vaiheessa. Ensin se lukee HTML:n, ja renderöinti tapahtuu myöhemmin, kun resursseja riittää. Yleensä se onnistuu. Mutta jos skripti kaatuu virheeseen, datapyyntö aikakatkaistaan tai jokin tiedosto on estetty robots.txt:ssä, Google indeksoi sen, mitä HTML:ssä oli — eli ei mitään.

Monet muut eivät renderöi lainkaan. Suurin osa muista hakuroboteista, tekoälypalvelujen botit ja linkkien esikatselut (Facebook, LinkedIn, Slack, WhatsApp) lukevat vain raakaa HTML:ää. Niille selaimessa renderöity sivu on tyhjä: jaetussa linkissä ei ole otsikkoa eikä kuvaa, eikä tekoälyhaulla ole mitään lainattavaa.

Ongelma ei siis ole React vaan se, missä HTML syntyy.

Ratkaisu: HTML syntyy palvelimella tai käännösvaiheessa

Kaksi tapaa, jotka kumpikin antavat hakurobotille heti valmiin sisällön:

  • Palvelinpuolen renderöinti (SSR) — palvelin kokoaa HTML:n jokaista pyyntöä varten.
  • Staattinen generointi (SSG) — HTML kootaan etukäteen käännösvaiheessa (build), ja palvelin vain lähettää valmiin tiedoston.

Next.js tekee tämän oletuksena. App Routerissa komponentit ovat palvelinkomponentteja, ja sivu generoidaan staattisena, ellei se tarvitse pyyntökohtaista dataa. Jokainen URL palauttaa oikean HTML:n sisältöineen; JavaScript tuo päälle vain interaktiivisuuden (tätä kutsutaan hydraatioksi).

Pikatesti: onko teksti HTML:ssä?

Avaa sivu, paina Ctrl+U (Macissa Cmd+Option+U) ja etsi jokin sivulla näkyvä lause. Ei kehittäjätyökalujen kautta — ne näyttävät sivun vasta JavaScriptin ajamisen jälkeen. Sama komentoriviltä:

curl -s https://sivustosi.fi/palvelut/ | grep -c "lause, joka näkyy sivulla"

Jos tulos on 0, sisältö syntyy vasta selaimessa. Search Consolen URL-tarkistustyökalu näyttää lisäksi, minkä HTML:n Google sai renderöinnin jälkeen.

Tarkistuslista Next.js-sivustolle

Palvelimella renderöity HTML on edellytys, mutta Next.js-sivuston hakukoneoptimointi ei lopu siihen. Tässä se, minkä pitää olla kunnossa jokaisella sivulla.

Jokaisella sivulla oma title ja metakuvaus. SPA-sovellusten yleisin virhe: sama otsikko jokaisessa URL-osoitteessa. Next.js:ssä sen määrittää metadata-vienti tai dynaamisilla sivuilla generateMetadata, ja se päätyy HTML:n <head>-osaan jo palvelimella, ei myöhemmin.

Canonical. Jokainen sivu kertoo, mikä URL on sen virallinen osoite — muuten kyselyparametrilliset ja kauttaviivalla päättyvät versiot voivat kilpailla saman sivun kaksoiskappaleina.

hreflang monikielisellä sivustolla. Jokainen kieliversio viittaa kaikkiin muihin ja x-default-versioon, ja viittausten on oltava molemminpuolisia. Omalla sivustollamme on viisi kieltä käännetyillä URL-osoitteilla, ja jokainen sivu saa canonicalin ja hreflang-tagit yhdestä paikasta — käsin ylläpidettynä tämä ei pysyisi oikein viidellä kielellä.

Generoidut sitemap.xml ja robots.txt. Next.js:ssä nämä ovat tiedostot app/sitemap.ts ja app/robots.ts. Sivukartta syntyy samasta datasta kuin sivut, joten uusi sivu ei voi unohtua siitä. Sivustomme generoi sivukartan käännösvaiheessa.

Rakenteinen data (JSON-LD). Yritys, palvelut, artikkelit, UKK ja murupolku <script type="application/ld+json"> -lohkossa. Sen on oltava alkuperäisessä HTML:ssä, ei selaimen myöhemmin lisäämänä.

Oikeat linkit. Google seuraa <a href>-linkkejä, painikkeita se ei klikkaa. Next.js:n Link-komponentti renderöi kunnollisen <a>-elementin. Navigointi, joka tapahtuu vain onClick-käsittelijän ja router.push()-kutsun kautta, on hakurobotille näkymätöntä.

Oikea 404. Puuttuvan sivun on palautettava HTTP-tilakoodi 404, ei 200 ja teksti ”sivua ei löytynyt” — jälkimmäistä Google kutsuu pehmeäksi 404:ksi (soft 404). Next.js:ssä tämän hoitaa notFound(). Staattisessa viennissä palvelimen on tarjoiltava 404-sivu oikealla tilakoodilla.

Yksi kauttaviivasääntö. /palvelut ja /palvelut/ ovat kaksi eri URL-osoitetta. Valitse toinen (trailingSlash Next.js:ssä), ohjaa toinen 301-uudelleenohjauksella ja varmista, että sisäiset linkit käyttävät samaa muotoa. Jos uusi sivusto korvaa vanhan, katso myös sivustouudistus ja SEO.

Kuvat mittojen ja alt-tekstin kanssa. width ja height varaavat tilan etukäteen, joten sisältö ei hypi (CLS). next/image vaatii ne joka tapauksessa. Staattisessa viennissä Next.js:n automaattinen kuvaoptimointi on pois päältä — kuvat on pakattava järkevään kokoon etukäteen.

Asiakaskomponentit vain sinne, missä on vuorovaikutusta. 'use client' lähettää komponentin selaimeen kaikkine tuonteineen. Valikko, lomake ja suodatin tarvitsevat sitä; tekstilohko ja alatunniste eivät.

Nopeus: Reactille ominaiset sudenkuopat

Core Web Vitals -mittareiden yleiskuva on käyty läpi artikkelissa sivuston nopeus: näin mittaat ja parannat sitä. React-sivustolla on sen lisäksi kolme omaa sudenkuoppaa.

JavaScriptin määrä ja hydraatio

Myös palvelimella renderöity sivu lataa JavaScriptin ja hydratoituu. Ennen kuin se on valmis, painikkeet eivät reagoi — tämä heikentää INP-arvoa etenkin edullisemmilla puhelimilla. Jokainen asiakaskomponentti ja jokainen kirjasto (karuselli, animaatiokirjasto, päivämääräkirjasto) kasvattaa pakettia. Raskas widget sivun alaosassa kannattaa ladata vasta tarvittaessa (next/dynamic).

Älä piilota otsikkoa JavaScriptin taakse

Yleinen tapa: sisältö ”häivytetään esiin”, ja siksi se on aluksi opacity: 0, kunnes skripti antaa luvan näkyä. Jos näin tehdään sivun pääotsikolle, LCP — Googlen tärkein latausnopeuden mittari — odottaa JavaScriptin latautumista ja hydraatiota. Jos skripti ei lataudu, otsikko jää näkymättömäksi.

Opimme tämän omalla sivustollamme. Etusivun otsikko on LCP-elementti, ja se käyttää nyt puhdasta CSS-animaatiota, joka käynnistyy ensimmäisestä piirrosta, eikä JavaScriptin ohjaamaa esiinhäivytystä. Vieritysefektit alempana sivulla ovat eri asia — otsikko ei riipu niistä.

Älä lähetä selaimeen kaikkia kieliä

Monikielisellä sivustolla on helppo tuoda asiakaskomponenttiin vahingossa koko käännössanakirja. Silloin jokainen kävijä lataa kaikkien kielten tekstit. Parempi malli: palvelinkomponentti lukee tekstin ja antaa asiakaskomponentille propseina vain ne merkkijonot, joita se tarvitsee.

Staattinen vienti: jokainen sivu on valmis tiedosto

Next.js osaa viedä koko sivuston pelkäksi HTML:ksi (output: 'export'). Tuloksena on kansio tiedostoja, jotka mikä tahansa web-palvelin tai CDN voi tarjoilla.

  • Nopea — palvelin ei laske mitään käynnin hetkellä.
  • Turvallinen — ei tietokantaa, hallintapaneelia eikä palvelinkoodia, johon hyökätä.
  • Edullinen ylläpitää — tavallinen staattinen webhotelli riittää.

Oma sivustomme on kokonaan staattinen vienti: Next.js (App Router), React ja TypeScript, viisi kieltä.

Hinta tästä: jokainen sisältömuutos tarkoittaa uutta käännöstä ja latausta palvelimelle. Yrityksen kotisivuille ja blogille, jotka muuttuvat kerran viikossa, se sopii hyvin. Jos sisältö muuttuu minuutin välein, käyttäjillä on tilejä tai tarvitaan hakua tietokannasta, tarvitset palvelinpuolen renderöintiä tai erillisen palvelun. Myös yhteydenottolomake tarvitsee pienen palvelinpuolen vastaanottajan.

Jos olet nyt WordPressissä ja harkitset siirtoa, lue siirtyminen WordPressistä ilman SEO:n menetystä ja laajempi vertailu WordPress vai koodipohjainen sivusto.

Milloin apua kannattaa pyytää

Jos sinulla on jo React-sivusto, tee kolme tarkistusta: katso kolmen sivun lähdekoodi, vertaa Search Consolen indeksoitujen sivujen määrää todelliseen sivumäärään ja katso, eroavatko otsikot sivujen välillä. Jos teksti puuttuu HTML:stä, metatagien hiominen ei auta — renderöinti on järjestettävä uudelleen, usein siirtymällä SPA:sta Next.js:ään.

Teemme kotisivuja Next.js:llä niin, että kaikki yllä mainittu on mukana alusta asti. Jos sivusto on jo olemassa mutta ei liiku Googlessa, aloita hakukoneoptimoinnista.

Lue myös

Liittyvät palvelut

Valmis viemään liiketoimintasi uudelle tasolle?

Ota yhteyttä jo tänään — luodaan yhdessä toimiva ja näyttävä kokonaisuus.

Ota yhteyttä