Next.js-sovelluksen voi julkaista tavalliselle tiedostopalvelimelle asettamalla output: 'export', kun sivujen sisältö ja reitit voidaan muodostaa koontivaiheessa eikä sovellus tarvitse Next.js-palvelinta käyttäjän pyyntöjen käsittelyyn. Tuloksena syntyy julkaistava tiedostohakemisto, joka sisältää HTML-sivut, selaimen tarvitsemat resurssit ja asiakasnavigoinnin aineiston.
Staattinen vienti sopii esimerkiksi tuotedokumentaatioon, kampanjasivustoon ja julkiseen tuoteluetteloon. Se voi sisältää myös vuorovaikutteisia React-komponentteja. Ratkaiseva suunnittelukysymys on, mitä tapahtuu sivuston koonnissa, mitä selaimessa ja mitä mahdollisessa erillisessä taustapalvelussa. Tässä oppaassa rajataan nämä vastuut ja viedään julkaisu asetuksista toimivaan tiedostopalveluun.
Milloin staattinen vienti sopii?
Aloita jokaisen ominaisuuden tarvitsemasta suoritusympäristöstä. Dokumentaation leipäteksti voidaan tuottaa etukäteen, välilehtien vaihtaminen toimii selaimessa ja palautteen tallentaminen edellyttää vastaanottavaa palvelua. Staattinen sivusto voi yhdistää nämä kaikki, mutta se ei itsessään tarjoa viimeistä osaa. Selain voi lähettää palautteen erilliseen rajapintaan, jos palvelun käyttöoikeudet ja selaimen verkkopyynnöt on suunniteltu sitä varten.
Server Component ei tarkoita automaattisesti pyyntökohtaista palvelintyötä. Viennissä komponentti voi lukea julkiseen sivuun tarvittavan aineiston koontiympäristössä ja muodostaa siitä julkaistavan tuloksen. Sen sijaan käyttäjän evästeen lukeminen saapuvasta pyynnöstä tarvitsee ajonaikaisen palvelimen. Next.jsin [staattisen viennin dokumentaatio](https://nextjs.org/docs/app/guides/static-exports) määrittelee tuettujen ominaisuuksien rajat.
| Tarve | Toteutus staattisessa julkaisussa |
|---|---|
| Sama sisältösivu kaikille | Muodosta sivu koontivaiheessa. |
| Suodatus jo ladatusta aineistosta | Suorita suodatus selaimessa. |
| Käyttäjäkohtainen tieto | Hae tieto erillisestä suojatusta palvelusta. |
| Next.jsin Server Action | Valitse palvelinympäristö tai toteuta kirjoitus erillisessä rajapinnassa. |
| Sisällön päivittyminen ilman uutta koontia | Hae muuttuva tieto selaimessa tai valitse palvelimella toimiva julkaisutapa. |
Kirjautumisnäkymän piilottaminen selaimessa ei suojaa viennin sisältämiä tiedostoja. Jos luottamuksellista tietoa päätyy HTML:ään tai muuhun julkaisuaineistoon, käyttöliittymän tarkistus tulee liian myöhään. Pidä suojattu aineisto palvelussa, joka tarkistaa jokaisen pyynnön käyttöoikeuden. Jos myös ensimmäisen sivuvastauksen täytyy olla käyttäjäkohtainen, tavallinen staattinen vienti ei täytä vaatimusta.
Ota vienti käyttöön
Lisää vientiasetus projektin olemassa olevaan Next.js-konfiguraatioon. Seuraava next.config.mjs sopii sivustolle, joka julkaistaan verkkotunnuksen juureen ja jonka palvelin osaa tarjota hakemistojen index.html-tiedostot. Kuvien optimointi poistetaan tässä esimerkissä käytöstä, jotta julkaisu ei tarvitse Next.jsin kuvapalvelua.
const nextConfig = {
output: 'export',
trailingSlash: true,
images: {
unoptimized: true,
},
}
export default nextConfig
Suorita projektin koontikomento. Jos package.json-tiedoston build-skripti käynnistää komennon next build, npm-projektissa komento on seuraava:
npm run build
Julkaisun lähde on oletuksena out-hakemisto kokonaisuudessaan. Älä poimi siitä vain HTML-tiedostoja: myös JavaScript, CSS ja navigointiin liittyvät tiedostot kuuluvat samaan julkaisuun. Koonti tarvitsee Node.js-ympäristön, vaikka valmiiden tiedostojen tarjoilu ei tarvitse Next.js-prosessia.
Älä sekoita vientiä asetukseen output: 'standalone'. Standalone-tulos sisältää käynnistettävän palvelimen ja sen tarvitsemia riippuvuuksia. Se ratkaisee palvelinjulkaisun paketointia, kun taas vienti muuttaa julkaisutavan tiedostojen tarjoiluksi. Näiden asetusten eroa kuvaa Next.jsin output-dokumentaatio.
Tee koonti jo ennen muun julkaisuketjun rakentamista. Epäonnistunut vienti voi paljastaa esimerkiksi yhteisessä layoutissa olevan pyyntökohtaisen riippuvuuden. Korjaa tällöin ominaisuuden sijoittelu tai arvioi julkaisutapa uudelleen; rajoituksen peittäminen ei tuota puuttuvaa palvelinta tuotantoon.
Sovita reitit tiedostopalvelimeen
Selaimessa tehty navigointi ja suora sivupyyntö kulkevat eri reittejä. Linkin napsautus voi toimia Reactin asiakasnavigoinnilla, vaikka saman osoitteen avaaminen uuteen välilehteen epäonnistuisi. Suorassa pyynnössä tiedostopalvelimen täytyy osata yhdistää osoite oikeaan HTML-tiedostoon ilman käynnissä olevaa Next.js-reititintä.
Asetuksella trailingSlash: true sivun /ohjeet HTML tuotetaan muotoon ohjeet/index.html. Ilman asetusta vastaava tiedosto on ohjeet.html. Valitse muoto palvelimen ominaisuuksien perusteella ja tarkista samalla, miten palvelin käsittelee osoitteet /ohjeet ja /ohjeet/. Next.jsin [trailingSlash-dokumentaatio](https://nextjs.org/docs/app/api-reference/config/next-config-js/trailingSlash) kuvaa asetuksen vaikutuksen vientiin.
Älä ota automaattisesti käyttöön yhden sivun sovelluksille tarkoitettua sääntöä, joka palauttaa juuren index.html-tiedoston jokaiseen tuntemattomaan osoitteeseen. Sivukohtaisessa viennissä tämä voi palauttaa väärän sivun ja onnistuneen HTTP-tilan osoitteelle, jota ei ole olemassa. Määritä palvelun oma virhesivukäytäntö käyttämään viennin 404.html-tiedostoa ja säilyttämään 404-tila.
Dynaaminen reittisegmentti tarvitsee julkaistavat arvot
Hakemisto app/tuotteet/[slug] ei luo rajatonta määrää tuotetiedostoja. Vientiin tarvittavat arvot määritellään generateStaticParams-funktiolla. Jos luetteloon lisätään koonnin jälkeen uusi tuote, sen sivu syntyy vasta uudessa koonnissa. Tämä on tärkeä ero palvelinympäristöön, jossa reittejä voidaan tietyillä asetuksilla muodostaa myös pyynnön yhteydessä.
Tarkista erityisesti reittiluettelon tietolähde. Jos sisällönhallinnan rajapinta palauttaa sivutettuja tuloksia, vain ensimmäisen erän hakeminen jättää osan sivuista viennin ulkopuolelle. Vertaa julkaistavien polkujen luetteloa odotettuun sisältöön ennen julkaisua. Sama tarkistus auttaa löytämään poistetut, luonnoksiksi muutetut ja keskenään päällekkäiset polut.
Tarkista alihakemisto, kuvat ja selainkoodi
Jos sivusto julkaistaan verkkotunnuksen juuren sijasta polkuun /opas, lisää asetuksiin basePath: '/opas' ennen koontia. Arvo sisällytetään selaimen koodiin, joten pelkkä tiedostojen siirtäminen toiseen hakemistoon ei päivitä sovelluksen käsitystä julkaisupolusta.
next/link huomioi basePath-asetuksen sivulinkeissä. Kaikki käsin kirjoitetut resurssipolut eivät kuitenkaan muutu mukana: esimerkiksi next/image-komponentin paikalliseen src-polkuun etuliite täytyy lisätä itse. Tarkista myös latauslinkit ja selaimen omat fetch-pyynnöt. Vinoviivalla alkava polku viittaa verkkotunnuksen juureen, vaikka nykyinen sivu sijaitsisi alihakemistossa.
assetPrefix palvelee eri tarkoitusta: sillä ohjataan Next.jsin staattisia JavaScript- ja CSS-resursseja esimerkiksi erilliseen jakeluverkkoon. Se ei korvaa sivuston basePath-asetusta eikä lisää etuliitettä automaattisesti public-hakemiston tiedostoviittauksiin. Näiden asetusten vastuut kannattaa tarkistaa Next.jsin vastaavista konfiguraatioviitteistä.
Kuvien tarjoilu ja selaimen ensimmäinen renderöinti
Esimerkin images.unoptimized tarjoaa lähdekuvat sellaisinaan. Se ei pienennä suurta kuvaa mobiililaitteelle eikä tuota uusia kuvaformaatteja. Valmistele sopivat kuvat etukäteen tai käytä erillistä kuvapalvelua ja sitä vastaavaa mukautettua loaderia. Säilytä myös kuvien mittasuhteet, jotta selain voi varata niille tilan.
'use client' ei tarkoita, että komponentti suoritettaisiin vain selaimessa. Client Components -komponenteistakin muodostetaan viennissä alustava HTML. Älä siis lue window- tai localStorage-arvoja suoraan komponentin alustavan renderöinnin aikana. Lue niitä esimerkiksi useEffect-koukussa tai käyttäjän käynnistämässä tapahtumankäsittelijässä. Pidä alkuperäinen näkymä vakaana, kunnes selaimen tieto on saatavilla.
Pidä julkaisu ja päivitykset ehjinä
Käsittele koontitulosta yhtenä julkaisuna. Jos uusi HTML ehtii palveluun ennen sen tarvitsemia JavaScript-tiedostoja, sivu voi näyttää sisältöä mutta vuorovaikutus tai navigointi rikkoutuu. Suosi hosting-palvelun julkaisumallia, jossa valmis tiedostojoukko vaihdetaan käyttöön yhtenä kokonaisuutena. Säilytä edellinen kokonaisuus palautusta varten.
Huomioi myös jo avoinna olevat välilehdet. Niiden lataama vanha koodi voi tarvita myöhemmin vanhan julkaisun resursseja. Jos julkaisujärjestelmä sallii sen, säilytä aiempien julkaisujen sisältötiivisteellisiä resursseja siirtymäajan. Pelkkä uuden julkaisun onnistunut etusivupyyntö ei osoita, että vanha istunto pystyy jatkamaan navigointia.
Suunnittele välimuistit tiedostotyypeittäin. Sisältötiivisteen nimessään sisältävät resurssit sopivat pitkään välimuistitukseen, koska muuttunut sisältö saa uuden nimen. Samassa osoitteessa päivittyvä HTML ja reittien muut päivittyvät tiedostot tarvitsevat päivitystarpeeseen sopivan käytännön. Määritä HTTP-otsakkeet tiedostopalvelimella tai CDN:ssä: staattinen julkaisu ei suorita Next.jsin palvelinlogiikkaa otsakkeiden lisäämiseksi.
Päivitys alkaa uudesta koonnista
Kun koontivaiheessa luettu sisältö muuttuu, käynnistä uusi koonti ja julkaise sen tulos. ISR tai palvelimelle lähetetty uudelleenvalidointipyyntö ei luo tiedostoja staattiseen hosting-palveluun. Jos sivun pieni osa tarvitsee jatkuvasti tuoretta tietoa, selaimessa tehtävä haku voi olla sopiva ratkaisu, kun lataus- ja virhetilat ovat näkyviä.
Myös selaimen koodiin sisällytetyt NEXT_PUBLIC_-muuttujat saavat arvonsa koonnissa. Hosting-palvelun ympäristömuuttujan vaihtaminen jälkikäteen ei muuta valmista JavaScriptiä. Aseta esimerkiksi julkinen rajapintaosoite oikeaksi ennen koontia. Toimintaperiaate kuvataan Next.jsin [ympäristömuuttujien dokumentaatiossa](https://nextjs.org/docs/app/guides/environment-variables).
Pidä koontiin tarvittavat salaisuudet koontiympäristössä. Salainen lukutunnus voi mahdollistaa aineiston haun ilman tunnuksen julkaisemista, mutta sen avulla haettu sisältö voi silti päätyä julkiseksi. Tarkista siis sekä tunnusten käsittely että tuotettujen tiedostojen sisältö. Ympäristömuuttujan nimi ei yksin ratkaise, mitä sovellus tulostaa sivulle.
Tee hyväksymistarkistus julkaistaville tiedostoille
Arvioi julkaisua valmiista out-hakemistosta palvelimella, joka vastaa tuotannon polku- ja virhesivukäytäntöjä. Kehityspalvelimen toiminta ei yksin varmista staattisen palvelun asetuksia. Tee tarkistus myös todellisessa alihakemistossa, jos tuotannon julkaisu käyttää sellaista.
- Avaa sisäsivu suoraan. Kirjoita selaimeen syvän reitin osoite ja päivitä sivu. Molempien täytyy palauttaa kyseisen sivun sisältö.
- Siirry sivulta toiselle. Käytä sovelluksen omia linkkejä ja selaimen paluutoimintoa. Tarkista verkkopaneelista, ettei navigointiresurssien haku epäonnistu.
- Avaa puuttuva osoite. Varmista oikea virhesivu ja HTTP-tila. Tarkista myös, ettei puuttuvan JavaScript-tiedoston vastauksena palauteta HTML:ää.
- Tarkista ladattavat resurssit. Käy läpi kuvat, fontit, tyylit ja tiedostolataukset. Kiinnitä huomiota verkkotunnuksen juureen osoittaviin polkuihin.
- Kokeile erillisen rajapinnan häiriötä. Käyttöliittymän pitää erottaa lataaminen, tyhjä tulos ja epäonnistuminen. Julkisen sivusisällön täytyy pysyä käyttökelpoisena suunnitellulla tavalla.
- Tarkista päivitys ja palautus. Julkaise esikatseluun muuttunut sisältö, pidä vanha välilehti avoinna ja varmista myös aiemman julkaisun palauttaminen.
Jos selain ilmoittaa JavaScript-tiedoston virheellisestä sisältötyypistä, tarkista ensin vastauksen sisältö. HTML-vastaus resurssipyynnössä viittaa usein väärään polkuun tai liian laajaan varasivusääntöön. Jos taas uusi sisältö näkyy vain välimuisti ohitettuna, selvitä HTML:n ja jakeluverkon välimuistikäytäntö ennen uuden koonnin käynnistämistä.
Hyväksy julkaisu vasta, kun suora sivulataus, asiakasnavigointi ja päivitys toimivat samassa hosting-ympäristössä. Näin tarkistus kohdistuu juuri siihen kokonaisuuteen, jota lukija käyttää: valmiisiin tiedostoihin, niiden osoitteisiin ja palvelimen antamiin vastauksiin.
Usein kysytyt kysymykset
Tarvitaanko Node.js-palvelin staattisen viennin julkaisuun?
Next.js-koonti tarvitsee Node.js-ympäristön, mutta valmiin viennin voi tarjota tavallisesta staattisesta hosting-palvelusta. Mahdollinen erillinen rajapinta tarvitsee oman suoritusympäristönsä.
Voiko staattisessa sivustossa olla hakua ja suodattimia?
Voi. Selain voi suodattaa ladattua aineistoa tai tehdä hakuja erilliseen palveluun. Hakutoiminto ei kuitenkaan luo uusia sivukohtaisia HTML-tiedostoja julkaisuun.
Miksi sisäsivu toimii linkistä mutta ei sivua päivitettäessä?
Tiedostopalvelin ei välttämättä yhdistä osoitetta oikeaan HTML-tiedostoon. Tarkista tuotetut tiedostot, loppuvinoviivan käsittely ja palvelimen polkusäännöt suoralla sivupyynnöllä.
Voiko lomakkeen lähettää Server Actionilla?
Ei staattisessa viennissä. Lähetä lomakkeen tiedot erilliseen vastaanottavaan palveluun tai valitse Next.jsille palvelinominaisuudet tarjoava julkaisutapa.




