Next.js: Peningkatan Pembangkitan Statis / SSG

Dibuat pada 25 Nov 2019  ·  250Komentar  ·  Sumber: vercel/next.js

Ringkasan

Izinkan Next.js menjadi hibrid sepenuhnya dengan menyediakan metode untuk melakukan pembuatan statis dan rendering sisi server pada basis per halaman.

  • Dua metode pengambilan data per halaman baru

    • getStaticProps - Ikut serta dalam pembuatan statis (SSG) pada waktu next build .

    • getServerSideProps - Ikut serta dalam rendering sisi server (SSR) yang merender sesuai permintaan.

  • Metode baru untuk menghasilkan secara statis (SSG) satu set rute dari sumber dinamis

    • getStaticPaths - Mengembalikan daftar parameter untuk rute dinamis untuk melakukan pembangkitan statis (SSG)

RFC ini secara eksklusif membahas penambahan API. Semua fungsi baru sepenuhnya kompatibel ke belakang dan dapat diadopsi secara bertahap. RFC ini tidak memperkenalkan penghentian.

Latar belakang

Saat membangun situs web atau aplikasi web, Anda biasanya harus memilih antara 2 strategi: Pembuatan statis (SSG) atau rendering sisi server (SSR).

Next.js sebagai gantinya memungkinkan Anda membangun aplikasi hybrid yang memungkinkan Anda memilih strategi mana yang digunakan per halaman. Dimulai dengan Next.js 9, halaman tanpa getInitialProps dioptimalkan secara statis dan menghasilkan file .html pada next build .

Namun, Anda mungkin ingin melakukan pengambilan data saat membuat halaman statis untuk kasus penggunaan khusus Anda.

Misalnya, untuk menghasilkan halaman pemasaran secara statis dari CMS atau bagian blog dari situs.

Menggunakan getInitialProps akan mengikutsertakan Anda ke dalam SSR dalam kasus itu.

Next.js saat ini memiliki perintah next export , yang membuat aplikasi sepenuhnya SSG, kehilangan sifat hybrid Next.js.

Jika Anda menggunakan next export dengan getInitialProps ada masalah lain yang muncul. getInitialProps dipanggil pada waktu pembuatan (yang sangat bagus), tetapi kemudian ketika Anda menggunakan next/link untuk berpindah antar halaman getInitialProps disebut sisi klien, alih-alih menggunakan next export hasil.

Ini juga berarti sumber data (titik akhir CMS / API) dipanggil langsung pada transisi sisi klien, jika sumber data Anda tidak aktif, transisi sisi klien akan terputus saat berpindah antar halaman.

Kami telah berkolaborasi dengan pengguna berat SSG dan next export di Next.js seperti HashiCorp (terima kasih @jescalan) dan secara ekstensif menyelidiki kendala yang tepat untuk memperkenalkan dua metode pengambilan data baru: getStaticProps dan getServerSideProps . Tetapi juga cara menyediakan parameter untuk menghasilkan halaman statis secara statis untuk rute dinamis: getStaticPaths (penggantian untuk exportPathMap yang per halaman).

Metode baru ini memiliki banyak keunggulan dibandingkan model getInitialProps karena ada perbedaan yang jelas antara apa yang akan menjadi SSG vs SSR.

  • getStaticProps menandai halaman yang akan dibuat secara statis pada waktu pembuatan (saat menjalankan next build )
  • getStaticPaths memungkinkan untuk mengembalikan daftar parameter yang dihasilkan pada waktu pembuatan untuk rute dinamis
  • getServerSideProps menandai halaman yang akan ditampilkan di sisi server pada setiap permintaan dan paling mirip dengan perilaku getInitialProps saat ini saat menggunakan server.

Memisahkan metode ini juga memungkinkan kita untuk menyediakan objek konteks yang benar yang dapat diketik menggunakan TypeScript. Saat Anda memilih strategi rendering tertentu, Anda mendapatkan nilai yang benar, saat ini dengan getInitialProps Anda harus menebak apa yang tersedia di SSG vs SSR saat menggunakan TypeScript.

Lebih jauh lagi, dengan membuat metode ini eksplisit, ini akan memungkinkan kita untuk mendokumentasikan perbedaan trade-off dengan lebih jelas.

Penerapan

Perhatikan bahwa semua metode ini adalah tingkat atas pada file komponen halaman dan tidak dapat disarangkan, mirip dengan getInitialProps .

getStaticProps

Menggunakan getStaticProps berarti halaman akan dirender secara statis pada waktu pembuatan (SSG).

Metode baru ini akan memungkinkan Anda melakukan pengambilan data untuk halaman yang akan dibuat secara statis menjadi file .html pada waktu next build .

Next.js juga akan secara otomatis menghasilkan file JSON yang menyimpan hasil getStaticProps pada waktu next build . Ini digunakan untuk perutean sisi klien.

Saat perutean sisi klien melalui next/link atau next/router , Next.js akan mengambil file JSON ini untuk mendapatkan alat peraga yang diperlukan untuk merender halaman sisi klien.

Properti dikembalikan di bawah kunci props sehingga opsi lain dapat diperkenalkan di masa mendatang.

// pages/index.js

// getStaticProps is only called server-side
// In theory you could do direct database queries
export async function getStaticProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

context akan berisi:

  • params - Parameter saat berada di rute dinamis.

getStaticPaths

Ini adalah ekstensi pada penggunaan getStaticProps untuk rute dinamis.

getStaticPaths menggantikan kebutuhan untuk memiliki exportPathMap dan berfungsi per halaman.

Karena Anda mungkin ingin membuat daftar url yang memiliki parameter dinamis secara statis, seperti pada contoh di bawah slug . Next.js akan menyediakan metode getStaticPaths yang memungkinkan untuk mengembalikan daftar url. Karena ini adalah metode async Anda juga dapat mengambil daftar tersebut dari sumber data seperti CMS Anda.

// pages/blog/[slug].js

// `getStaticProps` gets a `params` object holding the dynamic parameters
// For `/blog/hello-world` it would look like `{ slug: 'hello-world }`
export async function getStaticProps({ params }) {
  return {
    props: {}
  };
}

// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
  return {
    paths: [
      // This renders /blog/hello-world to HTML at build time
      { params: { slug: "hello-world" } }
    ]
  };
}

mundur

Dalam banyak kasus, Anda mungkin tidak ingin melakukan pra-render setiap rute yang mungkin dalam aplikasi Anda pada waktu pembuatan (misalnya jika Anda memiliki jutaan produk). Untuk alasan ini Next.js akan secara otomatis menghasilkan halaman fallback yang merupakan render halaman tanpa data (sehingga status pemuatan dapat ditampilkan) ketika halaman belum dibuat.

Perilaku penyajian yang tepat adalah:

  • Permintaan masuk

    • Next.js memeriksa apakah jalur dibuat pada waktu pembuatan

    • Jika jalur itu dibuat



      • melayani secara langsung



    • Jika jalur tidak dihasilkan



      • Melayani mundur


      • Next.js merender halaman (dengan data) di latar belakang dan menambahkannya ke daftar halaman yang dihasilkan


      • Permintaan selanjutnya ke jalur yang sama akan melayani halaman yang dihasilkan


      • Ini memastikan bahwa pengguna selalu memiliki pengalaman yang cepat dan tidak pernah mengalami TTFB lambat dari rendering server sambil mempertahankan build cepat dan properti generasi statis



Jika Anda ingin jalur yang tidak dibuat pada waktu pembuatan menghasilkan 404 yang juga dimungkinkan dengan mengembalikan fallback: false dari getStaticPaths

// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
  return {
    // Opt-out of the described fallback behavior
    fallback: false,
    paths: [
      // This renders /blog/hello-world to HTML at build time
      { params: { slug: "hello-world" } }
    ]
  };
}

getServerSideProps

Saat menggunakan getServerSideProps , halaman tidak dibuat secara statis (SSG) dan sebaliknya dirender sesuai permintaan pada setiap permintaan ke server (SSR).

Next.js juga akan secara otomatis mengekspos titik akhir API yang mengembalikan hasil pemanggilan getServerSideProps . Ini digunakan untuk perutean sisi klien.

Saat perutean sisi klien melalui next/link atau next/router , Next.js akan mengambil titik akhir API yang terbuka ini untuk mendapatkan data JSON yang diubah menjadi properti yang diperlukan untuk merender halaman sisi klien.

Metode ini adalah yang paling mirip dengan getInitialProps , dengan perbedaan utama adalah getServerSideProps selalu dieksekusi di sisi server, bukan di browser. Baik pada rendering sisi server atau pengambilan API saat perutean sisi klien.

Demikian pula untuk getStaticProps properti dikembalikan di bawah kunci props .

// pages/index.js

// getServerSideProps is only called server-side
// In theory you could do direct database queries
export async function getServerSideProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

context akan berisi:

  • params - Parameter pada rute dinamis
  • req - Objek permintaan HTTP
  • res - Objek respons HTTP
  • query - String kueri (tidak sepenuhnya yakin tentang yang ini, tetapi mungkin diperlukan)

Ditulis oleh @timneutkens , @Timer , @ijjk , @lfades. Berkolaborasi dengan @rauchg , @jescalan dan lainnya

Komentar yang paling membantu

Dukungan Generasi Situs Statis (SSG) generasi berikutnya telah dirilis sebagai stabil di Next.js 9.3!

Rilis ini juga mencakup dukungan untuk "Mode Pratinjau", atau kemampuan untuk mengabaikan halaman yang telah diprarender secara statis dan merender halaman sesuai permintaan untuk pengguna yang berwenang .

Anda dapat membaca lebih lanjut tentang itu di posting blog kami. Jika Anda lebih paham, langsung buka dokumen kami!

Semua 250 komentar

export async function getStaticProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

Saya tertarik untuk melihat keadaan apa yang kita perlukan untuk mengembalikan data tambahan selain dari apa yang dapat ditampung dalam props . Saya menemukan penjelasan sebaris "untuk lebih mengontrol perilaku per halaman" agak kabur.

Terlihat sangat menarik! Apakah dia akan menjadi pengganti getInitialProps atau di sampingnya? Misalnya, untuk kasus penggunaan kami, API pengambilan data adalah layanan publik. Jadi pada navigasi sisi klien, kami mengharapkan klien untuk langsung memanggil lapisan API, sedangkan pada SSR server memanggilnya. Ke depan, apakah use case ini akan terus diselesaikan dengan metode sebelumnya?

Saya tertarik untuk melihat keadaan apa yang kami perlukan untuk mengembalikan data tambahan selain dari apa yang dapat ditampung dalam props . Saya menemukan penjelasan sebaris "untuk lebih mengontrol perilaku per halaman" agak kabur.

Ini lebih tentang pemeriksaan metode di masa mendatang sehingga memungkinkan kami untuk memperluasnya nanti jika diperlukan.

Terlihat sangat menarik! Apakah dia akan menjadi pengganti getInitialProps atau di sampingnya? Misalnya, untuk kasus penggunaan kami, API pengambilan data adalah layanan publik. Jadi pada navigasi sisi klien, kami mengharapkan klien untuk langsung memanggil lapisan API, sedangkan pada SSR server memanggilnya. Ke depan, apakah use case ini akan terus diselesaikan dengan metode sebelumnya?

Secara umum perilaku itu memiliki beberapa kelemahan, misalnya pengambilan air terjun yang bisa lambat dari area tertentu di seluruh dunia. Pendekatan getServerProps memungkinkan cache respons lebih efisien.

Ini terlihat sangat menarik! Ide yang keren!

Saya memiliki kekhawatiran tentang penyebaran meskipun ...

Mari kita bayangkan saya menjadi tuan rumah di Now.
Untuk penerapan pertama, jelas bahwa seluruh aplikasi dibangun di atas penerapan.

Kemudian, saya mengubah beberapa konten di CMS dan mencari untuk memicu pembangunan kembali halaman SSG saja, tetapi kode aplikasi tidak berubah.

Segera alarm berbunyi, bahwa dalam hal ini jika saya memicu build, ada dua kemungkinan solusi:

1) Tidak ada yang dibangun kembali, karena semuanya di-cache - tidak ada kode yang berubah dan blabla.
2) Saya --force itu, dan sekarang "semuanya" akan dibangun kembali, tetapi saya hanya meminta halaman SSG untuk dibangun kembali.

_Ini hanya hipotesis, karena itu tergantung pada sistem build itu sendiri - seberapa sadar mereka tentang Next_

Ini mungkin akan mempengaruhi solusi hosting lainnya.

Selanjutnya sendiri memiliki .next/cache ... bagaimana ini akan bermain di sekitar itu?

@joltmode itu pada dasarnya adalah kasus untuk setiap generator situs statis saat ini. .next/cache dipertahankan di antara penerapan di Now dan digunakan kembali. Ingatlah bahwa saat ini Anda mungkin menggunakan getInitialProps untuk kasus ini dengan caching (berpotensi https://zeit.co/blog/serverless-pre-rendering), yang secara dinamis merender dalam fungsi tanpa server dan kemudian menyimpan di CDN kami, ini perilaku masih baik-baik saja dan akan terus berfungsi jika Anda menggunakan getServerProps .

Benar-benar luar biasa, akan cocok dengan cara kami menggunakan Next untuk proyek pelanggan, dan akan menghapus beberapa kode boilerplate yang kami salin.

Satu hal yang perlu dipertimbangkan adalah penamaan getStaticProps dan getServerProps, jika mereka mengembalikan { props } dan kemungkinan opsi lain di masa mendatang, apakah *Props tidak akan membingungkan? Mungkin getStaticConfiguration, getStaticSetup, getStaticOptions akan lebih umum?

@kibs nilai kembalian akan selalu berhubungan dengan bagaimana alat peraga ditangani. Jadi penamaan baik-baik saja imo.

Ini luar biasa! Ini memecahkan setiap kasus penggunaan dan kebutuhan yang baru-baru ini atau dapat saya pikirkan saat mengembangkan aplikasi web pribadi dan profesional. Anda baru saja mencegah saya memulai generator situs hybrid saya sendiri, terima kasih!

Saya juga dapat menghubungkan metode baru yang lebih baik dari sebelumnya getInitialProps() dan exportPathMap() , yang terdengar agak membingungkan bagi saya pada awalnya ketika saya mulai menggunakan Next.js dan menggali SSR / SSG. Pendekatan per halaman juga lebih masuk akal bagi saya.

Tidak sabar untuk mencoba ini!

Hanya catatan tambahan: dalam contoh terakhir saya pikir getServerProps() tidak memiliki parameter context .

Hanya catatan tambahan: dalam contoh terakhir saya pikir getServerProps() tidak memiliki parameter konteks.

Tetap!

Ini terdengar bagus! Saya hanya ingin tahu dari perspektif pengguna TypeScript jika memiliki getStaticProps , getStaticPaths dan getServerProps sebagai metode statis pada komponen halaman (seperti getInitialProps saat ini) akan lebih mudah untuk mengetik/menggunakan dengan benar.

const Page: NextPage<Props> = (props) => ...

// Explicit types needed here
export const getStaticPaths: NextGetStaticPaths<Params> = () => ...
export const getStaticProps: NextGetStaticProps<Props, Params> = (context) => ...
export const getServerProps: NextGetServerProps<Props> = (context) => ...

export default Page

// vs.

const Page: NextPage<Props, Params> = (props) => ...

// Static method types come from NextPage<Props, Params>
Page.getStaticPaths = () => ...
Page.getStaticProps = (context) => ...
Page.getServerProps = (context) => ..

export default Page

@herrstucki masalah dengan pendekatan itu adalah menjadi jauh lebih sulit untuk menggoyang pohon (baca: hampir tidak mungkin). Yang berarti kode yang tidak perlu akan dikirimkan ke browser.

@timneutkens poin bagus ... tetapi apakah file terpisah tidak akan lebih masuk akal? Atau sesuatu seperti ini _reliably_ pohon-bisa digoyahkan?

// This should all be removed in client-side code …
import {fetchQuery, queryTag} from 'big-data-fetching-lib';
const query = queryTag`...`
export const getStaticProps = async () => ({ props: await fetchQuery(query) })

// Only this should be included client-side
export default (props) => ...

@herrstucki kami dapat dengan andal menggoyang pohon itu, tetapi kami juga masih mendiskusikan untuk memiliki file terpisah. Secara pribadi saya lebih suka pendekatan file tunggal.

Terlihat sangat menarik! Apakah dia akan menjadi pengganti getInitialProps atau di sampingnya? Misalnya, untuk kasus penggunaan kami, API pengambilan data adalah layanan publik. Jadi pada navigasi sisi klien, kami mengharapkan klien untuk langsung memanggil lapisan API, sedangkan pada SSR server memanggilnya. Ke depan, apakah use case ini akan terus diselesaikan dengan metode sebelumnya?

Secara umum perilaku itu memiliki beberapa kelemahan, misalnya pengambilan air terjun yang bisa lambat dari area tertentu di seluruh dunia. Pendekatan getServerProps memungkinkan cache respons lebih efisien.

Tentu, tapi saya sedang berbicara tentang menghindari RTT ke server reaksi sama sekali. Pertimbangkan kasus di mana output SSR dari server di-cache di CDN / cache server proxy. Jika digabungkan dengan pengambilan data untuk navigasi klien secara langsung memanggil lapisan API yang berbeda (umum untuk web/aplikasi/semua klien), berarti lapisan server Next.js tidak harus ditingkatkan sebanyak dalam skenario lalu lintas tinggi.

Saya memahami titik pengambilan air terjun Anda, tetapi memberi konsumen kemampuan untuk memperlakukan server Berikutnya sebagai lapisan SSR vs sumber data akan memungkinkan penyiapan penskalaan yang jauh lebih baik.

Terlihat sangat menarik! Apakah dia akan menjadi pengganti getInitialProps atau di sampingnya? Misalnya, untuk kasus penggunaan kami, API pengambilan data adalah layanan publik. Jadi pada navigasi sisi klien, kami mengharapkan klien untuk langsung memanggil lapisan API, sedangkan pada SSR server memanggilnya. Ke depan, apakah use case ini akan terus diselesaikan dengan metode sebelumnya?

Secara umum perilaku itu memiliki beberapa kelemahan, misalnya pengambilan air terjun yang bisa lambat dari area tertentu di seluruh dunia. Pendekatan getServerProps memungkinkan cache respons lebih efisien.

Tentu, tapi saya sedang berbicara tentang menghindari RTT ke server reaksi sama sekali. Pertimbangkan kasus di mana output SSR dari server di-cache di CDN / cache server proxy. Jika digabungkan dengan pengambilan data untuk navigasi klien secara langsung memanggil lapisan API yang berbeda (umum untuk web/aplikasi/semua klien), berarti lapisan server Next.js tidak harus ditingkatkan sebanyak dalam skenario lalu lintas tinggi.

Saya memahami titik pengambilan air terjun Anda, tetapi memberi konsumen kemampuan untuk memperlakukan server Berikutnya sebagai lapisan SSR vs sumber data akan memungkinkan penyiapan penskalaan yang jauh lebih baik.

Saya pikir Anda salah paham bahwa perilaku baru ini berarti Anda benar-benar dapat men-cache hasil lengkap pada CDN mengingat CDN mendukung respons dinamis. Ini sebelumnya tidak dapat diandalkan dengan getInitialProps.

@timneutkens Saya bermain-main dengan kenari, mencoba babel-plugin-preval ke getStaticProps . Saya mengalami masalah dengan fs .

Saya mencoba membaca file .md dari direktori ./pages/blog/ dan mengulanginya sehingga saya dapat membuat halaman indeks blog dengan semua posting saya

import React from 'react';
import Link from 'next/link';
import fs from 'fs-extra';

const Index = ({ posts }) => (
  <div>
    Hello World. <Thing msg="hello" />
    <Link href="/thing">
      <a>About</a>
    </Link>
    {posts.map(p => (
      <div key={p.title}>{p.title}</div>
    ))}
  </div>
);

Index.getStaticProps = async () => {
  const items = await fs.readdir('./pages/blog');
  items.forEach(path => /* .... do some stuff ... */ )
  return { props: { posts: items } };
};

export default Index;

Kode ini menyebabkan kesalahan ini:

Module not found: Can't resolve 'fs' in '/Users/jared/Downloads/nextjs-typescript-template/node_modules/fs-extra/lib'

IIRC dari Razzle, kesalahan ini ada hubungannya dengan stub sistem file webpack (atau kekurangannya). Saya pikir saya pernah memperbaikinya dengan Razzle dengan menambahkan ini ke konfigurasi webpack.

node: {
  fs: "empty";
}

Saya mencoba next.config.js ini, tetapi itu hanya membuat kesalahan hilang. Tampaknya fs / fs-extra tidak benar-benar berfungsi, atau berhasil dan mungkin jalur tidak (tidak jelas bagi saya). Ada pemikiran tentang itu?

Pertanyaan saya yang lain, secara lebih umum, adalah apa yang Anda bayangkan tentang praktik terbaik untuk menggunakan import vs. require di getStaticProps . Jika saya tidak salah, cuplikan saya di atas akan mencoba mengimpor fs-extra di Bereaksi secara isomorfik??. Apakah dengan demikian lebih baik mengubah impor menjadi kebutuhan sebaris seperti ini?

js Index.getStaticProps = async () => { const fs = require('fs-extra'); // only require when needed at SSG const props = await fs.readdir('./pages/blog'); return { props: { posts } }; };

Saya pikir Anda salah paham bahwa perilaku baru ini berarti Anda benar-benar dapat men-cache hasil lengkap pada CDN mengingat CDN mendukung respons dinamis. Ini sebelumnya tidak dapat diandalkan dengan getInitialProps.

Ah, kurasa aku mengerti maksudmu. Apakah itu berarti bahwa getServerProps pada generasi SSR pertama akan membuat titik akhir yang unik, dalam hash yang dapat dialamatkan konten, mungkin di URL, mungkin yang kemudian dapat kita tembolok di CDN? Satu-satunya kelemahan dari ini adalah bahwa cache tersebut tidak dapat dibagikan antara aplikasi non Next (android / ios) dan aplikasi Next. Selain itu, dengan sumber data eksternal, arahan kontrol cache berada di hulu, tetapi di sini karena Next akan bertanggung jawab untuk menyajikan data, kita memerlukan API atau alat peraga untuk menentukannya untuk titik akhir data yang dihasilkan.

@jaredpalmer Saya berasumsi https://github.com/zeit/next.js/issues/9524#issuecomment -558628066 (termasuk kekhawatiran saya tentang keandalan tree-shakeability ) akan diselesaikan dengan memiliki file terpisah yang akan dikompilasi sepenuhnya secara terpisah dari kode bundel klien? Misalnya

pages/
    foo.js
    foo.data.js (<- exports getStaticProps etc.)

or:

pages/
    foo.js
pages-data/
    foo.js (<- exports getStaticProps etc.)

Goncangan pohon

Seperti biasa, terima kasih untuk semua yang kalian lakukan. Next.js benar-benar menyenangkan untuk digunakan, dan seperti yang telah saya katakan sebelumnya, hampir setiap rilis fitur memungkinkan kami _mengurangi_ ukuran basis kode yang saya kelola. Ini menakjubkan.

Sulit untuk mengkritik RFC ini karena, seperti yang tertulis, ini langsung berguna untuk BANYAK aplikasi. Namun, saya ingin membahas satu baris yang saya tidak yakin saya setujui:

" getStaticPaths menggantikan kebutuhan untuk memiliki exportPathMap dan berfungsi per halaman."

Dalam beberapa aplikasi, tidak praktis atau tidak mungkin untuk mengetahui rute pada waktu pembuatan. Beberapa contoh akan menjadi:

  • Halaman profil pengguna
  • Halaman produk (untuk perusahaan dengan inventaris yang cepat berubah)
  • Halaman detail Pesanan Penjualan

Rute untuk halaman seperti ini mungkin dalam bentuk /entity-name/entity-id dan rute dinamis Berikutnya bekerja dengan sangat baik karena Anda dapat melakukan hal-hal seperti router.push('/customers/[customerId]', '/customers/baer') . Masih ada tangkapan. Jika Anda berencana untuk menyajikan file-file ini secara statis dengan sesuatu seperti Sajikan, Netlify, NGINX, dll, Anda harus membuat satu set pengalihan sehingga pengguna tidak akan mendapatkan 404 pada penyegaran halaman dan, untuk melakukan itu, Anda masih perlu exportPathMap .

Berikut ini disalin, hampir apa adanya, dari basis kode yang saya kerjakan secara teratur:

const buildServeConfig = redirects => {
  const config = {
    public: `dist`,
    trailingSlash: true,
    rewrites: redirects
  };

  const outputPath = `${__dirname}/serve.json`;

  fs.writeFile(outputPath, JSON.stringify(config, null, 2), err => {
    if (err) {
      throw err;
    }
    // eslint-disable-next-line no-console
    console.log(`Generated: ${outputPath}`);
  });
};

...

exportPathMap: function(defaultPathMap, { dev, outDir }) {
  const redirects = Object.entries(defaultPathMap)
    // No need to create a redirect rule for `/dirname/` or `/dirname/index.html`
    .filter(([url]) => url !== `/` && url !== `/index`)
    .map(([url, { page }]) => ({
      // Replaces /[customerId] with /:customerId
      source: url.replace(/]/g, ``).replace(/\[/g, `:`),
      destination: `${page}/index.html`
    }));

  // By default, the routes are sorted such that a route like `/order/:orderId`
  // comes before `/order/new`. Since the `:orderId` portion of `/order/:orderId` 
  // is a wildcard, the route `/order/new` will be a match and consider `new` 
  // as a value for `:orderId`. To get past this, we sort the redirects by the 
  // number of parameters in ascending order.
  const sortedRedirects = [...redirects].sort(
    (currentRedirect, nextRedirect) =>
      currentRedirect.source.split(`:`).length >
      nextRedirect.source.split(`:`).length
  );

  buildServeConfig(sortedRedirects);

  return defaultPathMap;
}

Saya mengerti bahwa RFC ini tidak mencela atau menghapus API apa pun dan saya juga menyadari bahwa dimungkinkan untuk membuat pengalihan ini dengan melintasi direktori build sehingga meskipun sudah tidak digunakan lagi, saya memiliki pintu keluar yang bagus. Tapi, itu tidak cukup "menghilangkan kebutuhan untuk getStaticPaths ."

Sekali lagi, terima kasih atas perhatian Anda dalam menjalankan proyek ini

Apakah getStaticProps / getStaticPaths dan getServerProps saling eksklusif? yaitu apakah mungkin untuk memiliki bagian yang telah diprarender dan bagian yang dinamis pada saat yang bersamaan?

Ya mereka adalah sebagai satu adalah generasi statis dan satu adalah rendering sisi server.

Ini memperbaiki salah satu hal besar yang saya lewatkan dari Gatsby sebelum kami bermigrasi ke Berikutnya:

Kami memiliki file JSON monolitik (100 kbs) yang kami tarik datanya untuk membuat halaman kami yang tidak pernah berubah. Di Gatsby kami memuat file JSON ke dalam skema GraphQL dan menanyakan hal itu, hanya mengambil data yang kami butuhkan untuk merender halaman tertentu. Dengan Next, cara termudah/terbersih yang kami temukan untuk melakukan ini adalah import monolith from './monolith.json' , yang mengharuskan pengguna mengunduh seluruh file JSON.

RFC 100% ini membahas kasus penggunaan ini dan membawa Next selangkah lebih dekat untuk setara dengan Gatsby di area yang bersinar Gatsby (jelas, Gatsby tidak dapat melakukan runtime SSR, jadi saya hanya berbicara tentang render waktu pembangunan statis)

@timneutkens , terima kasih untuk RFC!

Saya memiliki kasus penggunaan untuk Next.js yang baru-baru ini saya diskusikan dengan @rauchg.

Next.js memberikan DX yang sangat halus dan beberapa default yang masuk akal. Jadi, saya tertarik menggunakan Next.js untuk aplikasi yang dirender hanya di sisi klien, aplikasi Smart TV.

Aplikasi Smart TV hampir merupakan aplikasi web klasik yang dijalankan oleh mesin browser TV:

  1. Aplikasi ini dikemas ke dalam bundel: gaya, skrip, gambar, _index.html_, sertifikat, dan file konfigurasi TV.
  2. Bundel dikirim untuk ditinjau ke toko aplikasi platform.
  3. Bundel tersebut kemudian diinstal dari toko sebagai aplikasi dan dijalankan oleh pengguna.

Masalahnya adalah bundel itu dihosting secara statis oleh perangkat TV itu sendiri dan tidak dimuat dari server. Dengan demikian, tidak ada opsi SSR yang dimungkinkan (Node.js tidak diekspos ke pengembang untuk tujuan ini). Tetapi aplikasi itu sendiri dinamis (katakanlah, Netflix).

Jadi, kita perlu menjalankan SPA yang di-host oleh server web statis.

Seperti yang saya pahami, menyisih dari getServerProps (atau getInitialProps ) sepenuhnya akan membantu menghindari SSR. Tapi apa yang terjadi dengan rendering dinamis pada klien? Dan bagaimana dengan perutean dalam kasus ini? Menurut RFC ini masalahnya belum teratasi. @timneutkens , bisakah Anda menyarankan cara terbaik untuk mengaktifkan rendering hanya sisi klien di Next.js? Dan apakah itu cocok dengan Next.js? Terima kasih!

PS Saya dapat membuat masalah untuk kasus penggunaan ini jika menurut Anda lebih baik untuk membahasnya secara terpisah.

@grushetsky dapatkah Anda membuat masalah yang berbeda. Ini adalah pertanyaan yang sama sekali berbeda dari apa yang sedang dibahas di RFC 👍

@timneutkens Janji RFC ini adalah salah satu hal yang membuat saya sangat bersemangat tentang Next! Hanya untuk memperjelas, getInitialProps akan tetap ada juga, bukan?

Benar @outdooricon -- getInitialProps akan tetap ada di masa mendatang.

Menurut RFC:

RFC ini secara eksklusif membahas penambahan API. Semua fungsi baru sepenuhnya kompatibel ke belakang dan dapat diadopsi secara bertahap. RFC ini tidak memperkenalkan penghentian.

RFC hebat, sangat bersemangat untuk ini!

Saya telah memikirkan getServerProps dalam kaitannya dengan kasus penggunaan tertentu, meletakkan hasilnya dalam cache. Karena ini diubah menjadi titik akhir API dan hasilnya dikirim ke komponen sebagai alat peraga, apakah ada cara yang ditentukan untuk memasukkan hasilnya ke dalam cache eksternal seperti Redux, GraphQL-caches dll, dll sisi klien?

Jika saya memahami getInitialProps dengan benar, karena statis dan asinkron, Next memiliki kesempatan untuk menunggu hingga selesai sebelum merender komponen untuk pertama kali. Ini memungkinkan kita memasukkan sesuatu ke dalam cache eksternal di sana. Ini tidak akan terjadi dengan getServerProps karena berjalan di server, dan meletakkan sesuatu di cache dalam siklus hidup komponen tampaknya berarti kita harus memiliki render di mana data belum tersedia di cache , bahkan jika itu tersedia di alat peraga?

Ini mungkin disengaja tentu saja dan saya mungkin kehilangan pendekatan, tetapi saya pikir saya akan bertanya apakah itu sesuatu yang telah dipertimbangkan?

Sunting: Saya kira ini juga berlaku untuk getStaticProps . 😄

Mungkin saya melewatkannya di suatu tempat, tetapi bagaimana kami menangani situasi ketika konten di-cache, tetapi diperbarui dalam db atau posting blog baru dibuat? Ada kebutuhan untuk melakukan build baru secara otomatis? Saya rasa begitu.

Pertama-tama! Proposal yang bagus, ini adalah peningkatan besar-besaran dari exportPathMaps pada kasus penggunaan kebanyakan orang. Ini benar-benar dihargai. Dengan itu, saya berjuang untuk memahami bagaimana kita akan dapat membuatnya bekerja dengan internasionalisasi rute.

Apakah ada saran tentang cara menangani rute awalan i18n? Kasus penggunaan khusus saya memerlukan beberapa ribu halaman dengan awalan dan url bahasa negara yang berbeda.

/nl/brillen
/gb/glasses
/es/gafas
...

Tampaknya getStaticPaths akan sangat membantu ketika awalan untuk url sudah dikenal, seperti pada contoh Anda (menggunakan /blog/[id].js ). Tetapi bagaimana menurut Anda implementasi getStaticPaths akan terlihat jika perlu menghasilkan jalur di tingkat root, dengan awalan dinamis (lang negara) dan jalur dinamis?

@reaktivo pages/[lang]/blog/[id].js -> di getStaticPaths berikan semua url untuk dirender secara statis.

@timneutkens Adakah ide kapan ini akan tersedia/dapat diuji?

Secara umum kami tidak memberikan ETA karena kami menguji fitur secara ekstensif terhadap aplikasi produksi untuk memastikan solusinya tepat.

Perbaikan ini benar-benar akan membuat saya mencela proyek fenomis "tidak terpelihara" saya (bereaksi ssg yang tidak digunakan siapa pun kecuali saya). Luar biasa melihat Next.js menambahkan bagian yang hilang ini!

Saya ingin mengklarifikasi keraguan. Mengingat penggunaan CMS seperti wordpress. Seperti yang saya pahami, dengan metode getStaticPaths saya akan mengambil semua posting dan meneruskan daftar seperti:

export async function getStaticPaths () {
  return [
    // This renders / blog / hello-world to HTML at build time
    {params: {slug: "hello-world"}}
  ];
}

Siput dari setiap posting akan digunakan dalam metode getStaticProps untuk mengambil konten.
Ini akan terjadi di npm build.
Pertanyaan saya adalah tentang posting baru yang akan ditambahkan setelah build.
Apakah metode getStaticProps akan digunakan untuk mengambil posting baru ini dengan slug?
Apakah postingan baru ini akan memiliki file .html seperti yang ada di build sebelumnya?
Saya suka bekerja dengan berikutnya dan dalam beberapa proyek yang saya miliki ini akan sangat bagus.

Tidak ada yang terkait langsung, tetapi dukungan tidak dapat memberi saya jawaban yang sesuai dengan pertanyaan saya.

Apa yang Anda sarankan di sini bisa menjadi solusinya, tetapi sementara itu, saya tidak dapat membuat nextJS untuk membangun JAMSTACK berdasarkan perubahan webhook.

jika saya memiliki getInitialProps, saya akan menjadi server-render.
Jika tidak, saya hanya CDNized, tapi tanpa pra-render bukan? Dan halaman akan tanpa konten selama XHR belum kembali (bye-bye SEO)

Apakah Anda memiliki contoh yang sedang berjalan dengan sekarang Jamstack dengan nextJS dan kami dapat melakukannya di netlify.

Terima kasih,
Andreas

Hai @ScreamZ - perubahan ini, menurut saya, yang memungkinkan situs yang sepenuhnya statis dibangun dengan nextjs. Kami telah dapat mengkompilasi situs nextjs menjadi statis menggunakan next export untuk waktu yang lama, tetapi masih akan mengambil data pada transisi rute sisi klien menggunakan getInitialProps . Dengan kemampuan untuk menggunakan getStaticProps , Anda dapat menjalankan transisi sisi klien tanpa data tambahan apa pun yang diambil -- semua data yang diambil di getStaticProps diambil sekali, pada waktu pembuatan, dan tidak diperbarui pada situs hidup kecuali Anda membangun kembali lagi. Ini adalah arsitektur klasik situs statis berbasis data, tautkan sumber data Anda ke host melalui webhook dan saat sumber data berubah, Anda memberi tahu host untuk membangun kembali situs Anda.

Ada banyak contoh situs web nextjs yang sepenuhnya statis, dan itu sepele untuk menjalankan situs nextjs di netlify. Situs web perusahaan saya saat ini berjalan di nextjs, dan dihosting oleh netlify, semoga ini menjadi contoh yang baik.

Sangat perlu dicatat bahwa layanan hosting zeit juga merupakan sesuatu yang patut dipertimbangkan dengan kuat. Harganya sangat mirip, dan integrasinya dengan situs nextjs tidak ada duanya - Anda benar-benar bahkan tidak perlu mengonfigurasi apa pun, Anda cukup menautkan github dan hosting zeit akan mengenali bahwa Anda menjalankan nextjs dan secara otomatis mengonfigurasi dan menyebarkan semuanya.

Ini bukan iklan dengan cara apa pun, saya tidak bekerja untuk semangat, hanya dukungan yang tulus. Anda benar-benar dapat membuatnya bekerja dengan netlify, dan saya sendiri memiliki beberapa situs sebagai buktinya. Tetapi Anda perlu memahami secara menyeluruh cara kerja nextjs, dan Anda harus memastikan semuanya dikonfigurasi dengan benar agar berjalan lancar di netlify. Jika Anda mencari hosting paling sederhana dan paling mudah untuk situs nextjs, saya akan mencoba hosting zeit.

@jescalan Terima kasih untuk berbagi yang luar biasa ini 🙏🏻

Saya tidak memiliki masalah menggunakan NextJS dengan netlify, karena Anda dapat menggunakan Publish directory untuk menentukan folder out . Tetapi pada zeit Sekarang, tidak ada cara untuk mengatakan, tolong jangan gunakan SSR tetapi gunakan statis dengan next export .

@ScreamZ ini agak benar, tetapi itu tergantung pada bagaimana tepatnya Anda mendefinisikan situs "statis penuh". Jika Anda menggunakan getStaticProps untuk semua halaman Anda dengan layanan hosting zeit, apa yang akan Anda dapatkan secara efektif sama dengan situs statis, meskipun tidak berjalan next export , karena semua halaman dengan getStaticProps dibuat hanya ketika situs di-deploy, dan disajikan langsung dari CDN setelah itu.

Perbedaan utama adalah sejauh yang saya tahu tidak ada cara untuk memaksa semua halaman menjadi statis di hosting zeit (edit: zeit baru-baru ini mengubahnya sehingga situs apa pun dengan konfigurasi yang berisi exportPathMap akan berjalan situs yang sepenuhnya statis, jadi ini tidak lagi benar). Halaman dengan getStaticProps berperilaku sama persis dengan halaman yang dihasilkan oleh next export -- satu salinan statis halaman disajikan langsung dari CDN pada setiap klik. Tetapi Anda juga dapat menjalankan beberapa halaman dengan getServerProps atau getInitialProps dan halaman tersebut akan berperilaku sebagai halaman yang dirender oleh server. Secara pribadi saya melihat ini sebagai keuntungan -- jika ada kebutuhan untuk rute SSR, Anda cukup menggunakan metode pengambilan data yang berbeda dan rute tunggal itu sekarang menjadi SSR, sementara semua rute Anda yang lain dapat tetap statis.

@jescalan Terima kasih,

Jadi hanya perlu menunggu untuk menerapkan ini, sementara itu akan menggunakan netlify untuk statis

Apakah ada cerita seputar konfigurasi SSG? Secara khusus kami ingin menggunakan artefak build bersama tetapi menjalankan next export dengan konfigurasi yang berbeda untuk QA/prod. Nilai konfigurasi ini hanya akan dibaca di getStaticProps . Apakah ini akan menggunakan serverRuntimeConfig atau publicRuntimeConfig atau process.env secara langsung?

@ScreamZ @jescalan Saya telah mendapatkan dukungan zero-config next export pada Sekarang hari ini bersama dengan @Timer (dia layak mendapatkan semua pujian). Anda dapat melakukan:

"build": "next build && next export"

Dan itu akan bekerja secara otomatis.

Beri tahu saya bagaimana kelanjutannya 🙏

Ya, saya adalah orang yang bertanya tentang dukungan dan mereka memberi tahu saya bahwa ini telah diterapkan dulu Sejauh yang saya lihat, Anda perlu mendefinisikan peta ekspor di konfigurasi?

@ScreamZ tidak, Anda bisa menambahkan next build && next export seperti yang ditunjukkan di atas dan itu akan berhasil.

@timneutkens Jika saya mengganti getInitialProps dengan getServerProps , apakah saya masih perlu menambahkan target: 'serverless' ke file konfigurasi untuk mengaktifkan Server Pre Rendering ? Terima kasih.

Bagaimana kita bisa mencoba ini?

Bagaimana kita bisa mencoba ini?

Saya kira semua metode ini saat ini membutuhkan awalan unstable_ untuk dikenali.

misalnya unstable_getStaticProps

@timneutkens

@ScreamZ @jescalan Saya telah mendapatkan dukungan zero-config next export pada Sekarang hari ini bersama dengan @Timer (dia layak mendapatkan semua pujian). Anda dapat melakukan:

"build": "next build && next export"

Dan itu akan bekerja secara otomatis.

Beri tahu saya bagaimana kelanjutannya 🙏

Skrip build saya melakukan lebih banyak hal tetapi sepertinya berfungsi seperti pesona:

"build": "graphql codegen && next build && npm run export",

Selain itu, itu bagus! Itu persis apa yang saya cari (Selamat tinggal GatsbyJS, kerangka kerja favorit saya sekarang kuat seperti Anda!)

Terima kasih banyak atas reaktivitas seperti itu.

Saya juga meningkatkan ke 9.1.6 dan saya terkejut melihatnya
Screenshot 2019-12-21 at 19 25 43

Saya pikir utas itu adalah RFC, sepertinya sudah dibuka untuk kita ahah, bukan?
Namun, jenis TypeScript tidak diaktifkan di 9.1.6.

Sial, aku sangat bersemangat untuk itu sekarang! 🤣

Pertanyaan terakhir:

  • Jika saya mendapatkannya, getInitialProps akan ditinggalkan di masa mendatang? Atau masih relevan dalam beberapa kasus? Sebuah contoh?
  • next export juga dapat ditinggalkan demi halaman dengan getStaticProps dan next build saja?

Terima kasih untuk alat yang hebat itu 🙏🏻

Jika saya mendapatkannya, getInitialProps akan ditinggalkan di masa mendatang? Atau masih relevan dalam beberapa kasus? Sebuah contoh?

Seperti yang dikatakan dalam RFC awal:

RFC ini secara eksklusif membahas penambahan API. Semua fungsi baru sepenuhnya kompatibel ke belakang dan dapat diadopsi secara bertahap. RFC ini tidak memperkenalkan penghentian.

Saya pikir utas itu adalah RFC, sepertinya sudah dibuka untuk kita ahah, bukan?

Bukan, kami sedang mencobanya di aplikasi ZEIT dan beberapa visibilitas muncul ke permukaan (misalnya pohon halaman yang Anda lihat).

ekspor berikutnya juga dapat dihentikan demi halaman dengan getStaticProps dan build berikutnya saja?

Benar, secara umum Anda tidak akan menggunakan next export . Itu akan disimpan untuk alasan kompatibilitas mundur tetapi secara umum Anda ingin membuat aplikasi hibrida karena memberi Anda semua manfaat ekspor dengan dukungan untuk fitur lain seperti rute API dan memilih rendering sisi server untuk beberapa halaman.

Bagaimana kita bisa mencoba ini?

Saya kira semua metode ini saat ini membutuhkan awalan unstable_ untuk dikenali.

misalnya unstable_getStaticProps

Sangat disarankan untuk tidak menggunakannya, ini eksperimental dan dapat terputus di antara rilis.

Jadi saya telah bermain-main dengan fitur ini dan saya telah mengamati bahwa file JSON yang berisi data halaman selalu diambil setelah mengakses halaman SSG dari halaman lain.

Apakah kalian berencana untuk melakukan optimasi preloading untuk file JSON?
Mungkin memuatnya terlebih dahulu ketika pengguna akan menavigasi ke halaman (yaitu: pengguna mengarahkan Tautan SSG) atau memuatnya sama seperti Anda sedang memuat halaman js lain yang direferensikan dari komponen Tautan.

Omong-omong, menyukai feataure itu!

Apakah kalian berencana untuk melakukan optimasi preloading untuk file JSON?

Ya.

Untuk apa nilainya, saya mendukung ekspor fungsi-fungsi ini yang dapat digoyahkan daripada file yang terpisah.

Apa status fitur ini? Apa pemblokirnya?

@mikestop melanjutkan RFC ini saat ini sedang diuji secara internal oleh tim kami, dan beberapa mitra terpilih. Anda dapat ikut serta dalam perilakunya yang awalan unstable_ , seperti yang disebutkan di atas ! 😄

Harap jangan memigrasikan beban kerja produksi ke metode baru, karena kami masih dapat memperbarui API dengan cara yang melanggar.

Secara pribadi, saya menggunakannya untuk membuat situs statis dari 8 hingga 20 ribu halaman (dengan kemungkinan memiliki beberapa permintaan dinamis di beberapa halaman). Ini bekerja dengan sangat baik (kecuali untuk batas file 10K pada Sekarang), satu-satunya hal yang saya rasa malu adalah bahwa tanpa metode getStaticPaths, getStaticProps dipanggil pada setiap pemuatan ulang. Satu perilaku yang mungkin baik adalah bahwa panggilan pertama membuat file json dan yang berikutnya menggunakannya.

Apakah Incremental Builds direncanakan? Jadi hanya konten baru/yang diubah yang dibangun kembali?

Anda dapat ikut serta dalam perilakunya yang awalan unstable_ , seperti yang disebutkan di atas !

Saya ingin menguji metode unstable_getServerProps , tetapi sepertinya metode itu diabaikan saat ini, dan saya tidak dapat menemukannya di mana pun di repo zeit/next.js . Apakah ini belum diterapkan, atau saya hanya melakukan kesalahan?

Apakah Incremental Builds direncanakan? Jadi hanya konten baru/yang diubah yang dibangun kembali?

Implementasinya dirancang dengan mempertimbangkan pembangunan kembali inkremental, tetapi belum didukung (juga tidak tercakup dalam RFC ini).

Yakinlah, arsitekturnya sudah siap dan kami akan menjelajahinya setelah fitur ini stabil.
Inilah mengapa getStaticProps didefinisikan per halaman, dan tidak sekali untuk seluruh aplikasi!

Saya ingin menguji metode stable_getServerProps, tapi sepertinya saat ini diabaikan [...]

getServerProps belum tersedia di pratinjau, maaf!

getServerProps belum tersedia di pratinjau, maaf!

Terimakasih atas peringatannya. Saya pasti akan menonton utas ini, karena ketika itu mendarat saya punya _bunch_ kode yang dapat diganti dengan mengganti nama satu fungsi! 😍

Mohon klarifikasi, saya tidak 100% yakin apakah getServerProps / getStaticProps saat ini tersedia untuk digunakan atau tidak.

Berdasarkan utas ini: Tidak

Tetapi jika itu masalahnya, maka saya bertanya-tanya mengapa terminal saya menyinggungnya ketika saya menjalankan next build jika belum tersedia? Melihat pesan tersebut meninggalkan saya dengan asumsi kerja awal bahwa metode ini dalam produksi, dan butuh beberapa saat untuk mengetahui bahwa mereka tidak. Hanya ingin tahu tentang alasannya atau jika ada sesuatu yang saya salah paham.

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

(pada versi berikutnya 9.1.6)

Terima kasih

@stevenjchang mereka tersedia menggunakan sintaks berikut di pages/**/*.js :

export function unstable_getStaticPaths() {} // return [{params: {...}}, ...]
export function unstable_getStaticProps({params: {...}) {} // return {props: {...}}

Dan saya juga harus menambahkan, mereka luar biasa, meskipun mereka masih agak kasar saat menggunakan server dev.

meskipun mereka masih agak kasar saat menggunakan server dev.
@mikestopcontinues

Bisakah Anda menjelaskan hal ini? Tidak ada orang lain yang memberi kami umpan balik negatif tentang pengalaman server dev, dan kami ingin menyelesaikannya!

@Timer Saya sangat suka api baru. Masalah utama saya selama dev adalah bahwa json diminta ulang di setiap pemuatan. Ini memperlambat pengujian, tetapi juga salah menggambarkan pengalaman pengguna saat benar-benar menjelajahi situs.

Dengan "di setiap pemuatan" maksud Anda memuat halaman? Atau membangun kembali? Atau...?

@mmmeff Setiap kali Anda menavigasi ke jalur yang sama, ia meminta ulang json. Jadi jika Anda mengklik bolak-balik antara dua halaman, Anda menghabiskan banyak waktu menunggu data.

@mikestop melanjutkan ini adalah perilaku yang dimaksudkan, karena data yang paling mutakhir seringkali lebih disukai dalam pengembangan. Akan terbuka untuk mendiskusikan beberapa heuristik yang lebih baik dalam edisi baru!

@timneutkens RFC ini terlihat sangat menjanjikan. Saya memiliki beberapa pertanyaan/kekhawatiran tentang keamanan, dan cara kerjanya dengan tepat.

Mari kita ambil kasus bisnis umum yang bergantung pada SSR dan SSG.

Konteks

Kami ingin menampilkan beberapa informasi di situs web (alias "aplikasi").
Informasi tersebut disimpan dalam BDD yang dapat diakses melalui GraphQL API.
Beberapa dari informasi tersebut bersifat publik, beberapa bersifat pribadi (yaitu: email/kata sandi pengguna).

Aplikasi ini menggunakan dua tahap:

  • Tahap "pementasan", di mana pelanggan dapat melihat perubahan waktu nyata di aplikasi pementasan (mereka memperbarui informasi tersebut melalui beberapa back-office atau yang serupa)
  • Tahap "produksi", di mana pelanggan tidak memiliki akses dan tidak dapat memperbarui apa pun sendiri. Untuk memperbarui aplikasi produksi, penerapan baru harus dilakukan. (mereka meminta penyebaran produksi baru dilakukan, dari back-office mereka)

Dalam skenario ini, kami menggunakan SSR dan SSG:

  • Aplikasi pementasan menggunakan SSR, karena mengambil data secara real-time dari GraphQL API (saat membuat halaman)
  • Aplikasi produksi menggunakan SSG, karena ketika penerapan baru dibuat, aplikasi ini mengambil data dari GraphQL API dan menghasilkan halaman statika darinya (oleh karena itu statis dan tidak akan berubah lagi, tidak ada kueri yang akan dibuat ke GraphQL API saat runtime (setidaknya tidak saat memuat halaman))

Skenario ini harus cukup umum, dan harus (IMHO) salah satu kasus penggunaan utama penggunaan SSG.
Aplikasi produksi tidak lebih dari snapshot dari aplikasi pementasan.

Beberapa pertanyaan:

  1. Apakah ini mungkin dengan RFC ini ? Memiliki aplikasi yang sama berperilaku berbeda berdasarkan "tahap" tertentu (produksi/pementasan)
  2. Bagaimana data diambil dari GraphQL API disuntikkan?

    • Dalam staging, mereka diambil secara dinamis melalui SSR, atau CSR saat pengguna menavigasi halaman (dan akan tersedia di browser jika diambil selama CSR)

    • Dalam produksi, mereka diambil pada waktu pembuatan, tetapi kemudian, apakah mereka disimpan dalam variabel global JS dan dengan demikian dapat dibaca oleh siapa saja? (masalah keamanan, karena kita harus waspada untuk tidak mengambil data sensitif yang mungkin tersedia di browser, mirip dengan cara melakukannya saat menggunakan CSR)

  3. Apakah Anda khawatir dengan pendekatan ini dengan SSR/SSG campuran? (keamanan, kinerja, pemeliharaan, dll.)

Kapan Anda berencana untuk merilis ini? Apakah ini akan menjadi pembaruan besar (v10), atau pembaruan yang kompatibel dengan versi sebelumnya?

Hai,

apakah Anda ada yang mencoba solusi ini dengan server khusus dan membuatnya berfungsi?

Contoh:

// server.js

const express = require('express');
const next = require('next');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = express();

  server.get('/blog/:id', (req, res) => {
    console.log('My params needed be passed to page:', req.params);
    return app.render(req, res, '/blogDetail', { id: req.params.id });
  });

  server.listen(port, err => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});

// blogDetail.js
export async function unstable_getStaticProps(props) {
  console.log('What is passed', props);

  return {};
}

const BlogPostPage = ({ post }) => {
  return <div>Hey</div>;
}

export default BlogPostPage;
# Terminal output

My params needed be passed to page: { id: 'test' }
What is passed { params: undefined }

Mengapa getStaticProps menyertakan string kueri? Saat ini saya memiliki halaman yang harus saya SSR hanya untuk mendapatkan params kueri tanpa rendering ulang. Menggunakan kait useRouter menyebabkan beberapa rendering ulang, karena kueri awalnya adalah objek kosong. Ini adalah halaman yang digunakan untuk pelacakan konversi, jadi jelas, itu bukan permulaan.

@pjaws RFC secara khusus menyebutkan getStaticProps adalah untuk pembuatan statis. HTML statis tidak dapat menerima string kueri.

Lalu mengapa bisa menerima parameter URL dinamis? Bagaimana itu berbeda?

Pada Selasa, 14 Januari 2020 pukul 01:30 Tim Neutkens [email protected]
menulis:

@pjaws https://github.com/pjaws RFC yang disebutkan secara khusus
getStaticProps adalah untuk pembuatan statis. HTML statis tidak dapat menerima
string kueri.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AMVRRIQCKDJNF4MPWSLYNV3Q5WA2NA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTIDN5
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AMVRRIRJXLYC4MC4U7DH7NDQ5WA2NANCNFSM4JRPBELQ
.

Karena di getStaticPaths Anda harus mengembalikan halaman yang akan dirender pada waktu build.

Perubahan ini terlihat sangat menjanjikan, kerja bagus seperti biasa! 👍

Saya bertanya-tanya tentang kasus penggunaan memiliki getInitialProps di _app.js untuk memenuhi kebutuhan data yang dibagikan di seluruh halaman (misalnya menyiapkan penyedia konteks). Apakah saya mengerti dengan benar bahwa tidak mungkin menggunakan getStaticProps dengan cara yang sama? Apakah hanya mungkin untuk mendefinisikannya di halaman individual?

Saya bertanya-tanya tentang kasus penggunaan getInitialProps di _app.js untuk memenuhi kebutuhan data yang dibagikan di seluruh halaman (misalnya menyiapkan penyedia konteks). Apakah saya mengerti dengan benar bahwa tidak mungkin menggunakan getStaticProps dengan cara yang sama? Apakah hanya mungkin untuk mendefinisikannya di halaman individual?

Benar, awalnya hanya untuk halaman individual. Mungkin mempertimbangkan kembali nanti. getInitialProps dari _app masih akan dipanggil saat mengekspor ke HTML statis sehingga Anda dapat secara bertahap pindah ke getStaticProps.

hai teman-teman, satu pertanyaan terkait - bagaimana aset akan diperlakukan? karena saya melihat sekarang bahwa jika saya menggunakan CMS tanpa kepala (bahkan wordpress atau graphcms atau apa pun), url aset digunakan dalam html statis.

Ada dua preferensi di sini - bahwa tautan aset digunakan seperti itu.
Tetapi lebih mungkin - unduh aset, buat html (tautkan ke sana secara lokal) dan kemudian lapisi CDN di depan. Ini adalah praktik yang jauh lebih dapat diterima.

Ini juga sangat terkait dengan penggunaan sistem penyebaran seperti Netlify - yang memiliki infrastruktur global yang jauh lebih cocok daripada sesuatu seperti DatoCMS atau Graphcms. Jadi jika saya menggunakan Netlify sebagai penyebaran, saya ingin semuanya dilayani dari domain Netlify dan membiarkannya bekerja dengan ajaib.

@sandys Jika saya mengerti dengan benar di https://github.com/zeit/next.js/issues/9054#issuecomment -570427085 Anda seharusnya mengunduh aset, simpan di bawah .next/static dan buat tautan diri Anda di getStaticProps .

Ada juga gagasan untuk memiliki rute api statis, tetapi saya tidak yakin persis bagaimana Anda akan mengontrol perilaku cache browser dengan itu.

@Janpot terima kasih telah menautkannya. Komentar di sana tampaknya menunjukkan bahwa hal ini harus dilakukan sendiri.

Silakan tambahkan permintaan saya untuk memiliki ini built-in. Mungkin #9054 lebih umum, tetapi saya berpikir dari perspektif SSG dan ini SANGAT penting.

Saya lupa menyebutkan, tetapi hashing aset juga penting untuk SSG.

@homoky , Belum bisa membuatnya bekerja, apakah Anda membuat kemajuan sementara itu?

@homoky , Belum bisa membuatnya bekerja, apakah Anda membuat kemajuan sementara itu?

Itu tidak mungkin dan tidak direncanakan juga: #10071

😢

@sandys sebenarnya solusinya jauh lebih sederhana ketika Anda menggunakan https://github.com/zeit/next.js/issues/9081 untuk menambahkan penulisan ulang dari misalnya /images ke CMS. Misalnya di ZEIT Sekarang hasil sudah akan di-cache ketika header yang benar ditambahkan, tidak perlu mengunduh tambahan (overhead besar saat dibuat).

@timneutkens terima kasih telah membalas.
Tidak sepenuhnya yakin apa yang Anda maksud. Jadi kami menggunakan netlify - apakah Anda menyarankan agar kami menyimpan url CMS seperti itu dan menempatkan lapisan CDN di atasnya?
saya tidak begitu yakin apakah netlify (cloudfront yang kami rencanakan untuk digunakan) dapat bekerja dengan mulus dengan semua layanan ini.

Jika gambar diunduh dan dijadikan bagian dari penerapan, maka seluruh masalah ini akan disederhanakan secara besar-besaran. Karena saya mengatur CDN ke cache dari url dasar (yang dalam kasus saya akan dilayani dari s3).

Tidak sepenuhnya yakin apakah solusi Anda didasarkan pada saya menggunakan Zeit SEKARANG

Jika gambar diunduh dan dijadikan bagian dari penerapan, maka seluruh masalah ini akan disederhanakan secara besar-besaran. Karena saya mengatur CDN ke cache dari url dasar (yang dalam kasus saya akan dilayani dari s3).

Ini sebenarnya membuat proses pembuatan jauh lebih kompleks dan 10x lebih lambat, jelas tidak sederhana.

Tidak sepenuhnya yakin apakah solusi Anda didasarkan pada saya menggunakan Zeit SEKARANG

Bekerja dengan setiap proxy di dunia. Termasuk cloudfront.

@timneutkens sebenarnya kami agnostik dengan waktu proses pembuatan. tidak masalah jika itu memakan waktu lebih lama. tetapi karena berbagai alasan (termasuk semua aset yang dilayani dari url dasar yang diketahui), akan sangat disukai untuk memasukkan ini ke dalam build.

Saya tentu tidak menganjurkan Anda mengaktifkan ini untuk semua orang. Banyak orang akan senang membuat tautan dalam ke CMS. Tetapi kami menjalankan situs dengan lalu lintas tinggi dan ini jelas merupakan sesuatu yang dibutuhkan situs seperti kami.

Juga, maafkan saya, tetapi saya tidak mengerti solusi Anda. bagaimana kita harus mengkonfigurasi ini? saya tidak memiliki kendali atas url mana yang digunakan CMS. Misalnya, Datocms mulai melayani dari www.datocms-assets.com/ . Bagaimana kita menggunakan solusi di #9081 ?

kami sebenarnya agnostik dengan waktu proses pembuatan. tidak masalah jika itu memakan waktu lebih lama

Ini mungkin benar untuk aplikasi Anda, tetapi itu tidak berlaku untuk sebagian besar aplikasi.

tetapi karena berbagai alasan (termasuk semua aset yang dilayani dari url dasar yang diketahui), akan sangat disukai untuk memasukkan ini ke dalam build.

Sebenarnya tidak harus seperti yang dikatakan, Anda dapat menggunakan penulisan ulang yang memproksi /images/* ke url cms, misalnya www.datocms-asset.com/* atau serupa. Dan kemudian cukup tautkan semua gambar menggunakan /images .

Perhatikan bahwa ini mulai keluar dari topik.

@sandys sebenarnya solusinya jauh lebih sederhana ketika Anda menggunakan #9081 untuk menambahkan penulisan ulang dari misalnya /images ke CMS. Misalnya di ZEIT Sekarang hasil sudah akan di-cache ketika header yang benar ditambahkan, tidak perlu mengunduh tambahan (overhead besar saat dibuat).

@timneutkens Hanya untuk memperjelas bagi saya. Dalam situasi yang ideal, Anda akan meng-hash gambar dan menyimpannya selamanya di browser di bawah url unik, dan pembuat konten dapat memperbarui file kapan pun mereka mau dengan nama yang sama di CMS. Jadi itu berarti dalam pengaturan yang Anda usulkan, CMS harus bertanggung jawab untuk:

  1. mengoptimalkan gambar
  2. hashing gambar dan sajikan di bawah hash ini
  3. berikan peta dari url gambar ke url gambar hash yang dapat diunduh di getStaticProps untuk memetakan ulang url gambar ke mitra abadi mereka di CMS

Yang, saya kira, bukan tidak mungkin. Hanya ingin memastikan bahwa ini adalah pengaturan yang diusulkan.

Penyedia CMS

@sandys ini tidak terkait dengan SSG RFC jadi jangan ragu untuk membuat masalah baru saat dirilis.

Namun, hanya ingin menyebutkan bahwa dalam semua pikiran kita, ini terkait erat dengan SSG. Karena kasus yang ideal adalah perintah ekspor SSG untuk melakukan ini. Ini tidak diperlukan dalam kasus lain secara umum.
Kasus terbaik adalah ini menjadi fitur opsional selama ekspor berikutnya.

Tapi, seperti yang Anda inginkan - hormati keputusan Anda.

Tapi itu adalah sesuatu yang bahkan tidak dilakukan next export saat ini. Oleh karena itu mengapa ini adalah hal yang sama sekali baru dan tidak terkait dengan RFC ini.

Itu juga tidak akan terjadi dengan getServerProps dan rendering sesuai permintaan.

Penyedia CMS

👍 ya, itu masuk akal. Tapi itu juga berarti bahwa jika Anda menggunakan gambar dalam proyek Anda dan Anda ingin mereka dioptimalkan dan di-cache, Anda memiliki 2 pilihan:

  1. buat pengaturan webpack khusus
  2. gunakan CMS eksternal

edit:

Dan jika saya mengerti benar, file-loader sudah termasuk untuk CSS. Bukankah ini masalah mengaktifkannya untuk JS juga?

@Janpot poin spesifik yang disebutkan Sandeep adalah bahwa url akan berasal dari sumber eksternal, bukan proyek itu sendiri. Menyertakan file-loader secara default adalah permintaan fitur yang berbeda.

Saya perhatikan bahwa untuk situs yang dikerahkan ke ZEIT Sekarang, ketika saya memiliki halaman dengan URL dinamis menggunakan API statis baru, untuk halaman yang belum dibuat secara statis menggunakan unstable_getStaticPaths , fungsinya unstable_getStaticProps berjalan di server saat runtime, daripada mengembalikan 404.

Misalnya saya memiliki halaman /blog/[slug].js , yang getStaticPaths mengembalikan array:

[{ params: { slug: 'hello' } }]

dan getStaticProps memiliki logika untuk membaca file berdasarkan siput. Ketika saya mengunjungi /blog/hello halaman diprarender seperti yang diharapkan, tetapi ketika saya mengunjungi halaman yang tidak valid seperti /blog/doesnt-exist , maka getStaticProps berjalan saat runtime dan saya mendapatkan kesalahan 500, bukan a 404. Atau jika saya menambahkan penanganan kesalahan, maka halaman akan dirender, bukan 404, meskipun tidak tercantum dalam output dari getStaticPaths .

Apakah logika ini disengaja?

Ini adalah peningkatan besar. Kami baru saja akan menulis beberapa skrip pra-pembuatan untuk melakukan hal ini.
Saya baru saja menguji memindahkan salah satu situs kami ke unstable_getStaticPaths dan unstable_getStaticProps pada Next 9.2, dan berhasil dengan baik.

Kami memiliki satu regresi dibandingkan dengan exportPathMap : saat membangun jalur menggunakan exportPathMap , Anda dapat menentukan sesuatu seperti ini:

{
 "/path/to/page": {page: "/index", query: { pageId: 123 } }
}

dan bangunan statis akan dibangun

/path
   /to
     /page
       index.html

Saat Anda mengembalikan yang setara dari unstable_getStaticPaths di templat [slug].jsx ,

[{ slug: '/path/to/page' }]

9.2 berikutnya menghasilkan '%2Fpath%2Fto%2Fpage` alih-alih direktori bersarang.

/%2Fpath%2Fto%2F
   index.html

Membangun direktori (mencocokkan perilaku exportPathMap yang ada) penting untuk bagaimana kita membangun halaman. Kami menggunakan file template tunggal tetapi jalur yang diterbitkan mungkin bersarang secara sewenang-wenang.

@dpfavand dalam hal ini Anda ingin menggunakan rute catch-all: https://nextjs.org/blog/next-9-2#catch -all-dynamic-routes

Mungkin kami dapat memperingatkan ketika Anda mencoba mengembalikan jalur termasuk garis miring, tetapi perilakunya benar saat menggunakan [slug].js , dalam kasus Anda, Anda ingin [...slug].js .

Kapan ini diharapkan mendarat? Apakah akan ada di patch 9.2 atau versi minornya sendiri?

Kami sangat menghargai semua kegembiraan seputar fitur ini. Seperti yang disebutkan di tempat lain, kami biasanya tidak membagikan garis waktu untuk fitur karena kami ingin memastikan mereka memiliki pengalaman pengembang yang tepat, kendala, dan pembuktian di masa depan.

Karena ini adalah fitur baru, ini akan menjadi minor.

Ya, saya akan mengerti itu secara normal tetapi blog 9.1.7 memberi kesan
itu sudah keluar di alam liar.

Pada Jumat, 17 Januari 2020 pukul 17:05 Tim Neutkens [email protected]
menulis:

Kami sangat menghargai semua kegembiraan seputar fitur ini. Seperti yg disebutkan
di tempat lain kami biasanya tidak membagikan garis waktu untuk fitur seperti yang kami inginkan
memastikan mereka memiliki pengalaman, kendala, dan masa depan pengembang yang tepat
pembuktian.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=ADKINGF724256WCEFHBFIH3Q6ITRXA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVX5HJKTDN5WWK3JKTDN5W
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/ADKINGBVCG6MFMOG5U2FGMDQ6ITRXANCNFSM4JRPBELQ
.

>

Lassiter Gregg
[email protected] [email protected]
sel (832) 495-9903

Apakah ada yang seperti getStaticProps tetapi itu hanya berjalan sekali untuk seluruh aplikasi, bukan per halaman?

Kasus penggunaan saya adalah saya memiliki React Context ( PricingPlansContext ) yang digunakan oleh banyak halaman dan saya ingin data (paket harga) diambil dari server eksternal saya hanya sekali, pada waktu pembuatan ( next export ). Tidak pernah saat runtime dan tanpa harus menambahkan getStaticProps dari setiap halaman.

EDIT: Menemukan komentar terkait di atas: https://github.com/zeit/next.js/issues/9524#issuecomment -574179540. Semoga bisa dipertimbangkan.

Saya menggunakan babel plugin-preval` untuk itu, meskipun saya juga melihat orang menulis
json dalam exportPathMa() dengan next.config.js, yang kemudian mereka impor
dalam kode mereka.

Saya akhirnya menulis file json menggunakan skrip npm untuk saat ini, tetapi terima kasih telah menyarankan exportPathMap, mungkin itu tempat yang lebih baik.

@dpfavand dalam hal ini Anda ingin menggunakan rute catch-all: https://nextjs.org/blog/next-9-2#catch -all-dynamic-routes

Mungkin kami dapat memperingatkan ketika Anda mencoba mengembalikan jalur termasuk garis miring, tetapi perilakunya benar saat menggunakan [slug].js , dalam kasus Anda, Anda ingin [...slug].js .

@timneutkens terima kasih atas tindak lanjutnya. Saya sudah mencoba dua metode tanpa hasil. Pada dasarnya ketika menentukan nilai slug sebagai string dalam getStaticPaths , itu tidak diteruskan ke getStaticProps sama sekali. Saat mengembalikan nilai slug sebagai array, build gagal karena nilainya harus berupa string.

Kasus 1, Dengan asumsi file pages/[...slug].jsx , slug sebagai string:

export async function unstable_getStaticPaths() {
    return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

Dalam kasus di atas, params di getStaticProps adalah objek kosong - tidak ada kunci slug .

Kasus 2, pages/[...slug].jsx , siput sebagai array,

export async function unstable_getStaticPaths() {
    const allPaths = Object.keys(pathMap).map(slug => ({ params: { slug } }));
    return [{ params: { slug: ['en', 'about'] } }];
}
export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

Dalam kasus 2, build gagal dengan

> Build error occurred
{ Error: A required parameter (slug) was not provided as a string.
    at _validParamKeys.forEach.validParamKey (/project/node_modules/next/dist/build/utils.js:21:569)
    at Array.forEach (<anonymous>)
    at toPrerender.forEach.entry (/project/node_modules/next/dist/build/utils.js:21:495)
    at Array.forEach (<anonymous>)
    at Object.isPageStatic (/project/node_modules/next/dist/build/utils.js:17:122)
    at process._tickCallback (internal/process/next_tick.js:68:7) type: 'Error' }

Saya hanya melihat params jalur dalam contoh getStaticPaths atas. Apakah mungkin untuk jalur SSG yang menyertakan parameter kueri? Sebagai contoh:

/store/widgets/circles-n-squares?sort=price&minWeight=2&color=black

Saya terutama berpikir dari perspektif situs e-niaga, di mana akan sulit untuk mencakup setiap aspek pencarian produk di pathname dari sebuah url.

Saya memposting pesan di sini baru-baru ini dan belum mendapat balasan - pada dasarnya, getStaticProps berperilaku seperti getServerProps ketika sebuah situs disebarkan ke ZEIT Now (yaitu mengabaikan getStaticPaths dan menangani permintaan dinamis) - Saya pikir ini adalah bug?

@dpfavand saya juga mengalami hal yang sama! Mencoba membangun situs pemula untuk agilitycms dan nextjs dengan perutean halaman dinamis berdasarkan halaman di CMS.

@timneutkens terima kasih atas tindak lanjutnya. Saya sudah mencoba dua metode tanpa hasil. Pada dasarnya ketika menentukan nilai slug sebagai string dalam getStaticPaths , itu tidak diteruskan ke getStaticProps sama sekali.

Kasus 1, Dengan asumsi file pages/[...slug].jsx , slug sebagai string:

export async function unstable_getStaticPaths() {
  return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
  console.log('params', params);
  return { slug: params.slug };
}

Dalam kasus di atas, params di getStaticProps adalah objek kosong - tidak ada kunci slug .

BTW, dunia kecil! Sekali lagi terima kasih telah berbicara di fastr_conf.

Hai @timneutkens ,

Saya sangat senang dengan ide membuat next.js berperilaku seperti generator situs statis.

Saya ingin bertanya bagaimana metode getStaticProps dan getStaticPaths dapat digunakan jika sebagian besar data diminta sekali dan kemudian digunakan untuk menghasilkan halaman yang berbeda.

Misalnya, saya menggunakan klien JavaScript SDK dari CMS berbasis API yang memiliki metode untuk mengambil semua objek yang tersedia. Beberapa objek ini mewakili halaman situs.

const entries = await cmsSdkCient.getEntries();

Sampai sekarang, saya telah menggunakan metode exportPathMap untuk mengambil semua entri dari CMS sekaligus dan menghasilkan peta antara jalur halaman ini dan datanya. Fungsi exportPathMap melakukan dua hal:

  1. Menyediakan peta halaman dengan datanya dan ssr: true yang digunakan oleh getInitialProps pada waktu ekspor
  2. Menulis data yang sama, kali ini dengan ssr: false , ke file init-props.json , ditempatkan di folder yang cocok dengan jalur setiap halaman. Kemudian, ketika getInitialProps dipanggil dari klien, data yang dibutuhkan diambil dari init-props.json halaman yang cocok.


next.config.js menggunakan exportPathMap

module.exports = {
  exportTrailingSlash: true,
  exportPathMap: (defaultPathMap, { outDir }) => {
    // load data from CMS
    const objects = await cmsSdkCient.getEntries();

    // create map between page paths and page data
    return objects.reduce((accum, object) => {

      // if the object does not have a slug, it is not a page
      if (!object.slug) return accum;

      const pagePath = '/' + object.slug;
      const ssrQueryData = Object.assign({ ssr: true }, object);
      const clientQueryData = Object.assign({ ssr: false }, object);

      // generate the map for export phase with {ssr: true}
      accum[pagePath] = {
        // using additional fields from the page object,
        // the pageFromPagePath() computes which page file should
        // be used to render the page object
        page: pageFromPagePath(object),
        query: ssrQueryData
      };

      // write json files that will be loaded by client
      if (outDir) {
        const jsonFilePath = path.join(outDir, _.trim(pagePath, '/'), 'init-props.json');
        fse.outputFileSync(jsonFilePath, JSON.stringify(clientQueryData));
      }

      return accum;
    }, {});
  }
}


halaman/halaman_saya.js menggunakan getInitialProps

Index.getInitialProps = async (context) => {
  const ssr = _.get(context, 'query.ssr', false);
  if (ssr) {
    // we are on server, return the data
    return _.get(context, 'query', {});
  } else {
    // we are on client side, request the data through /init-props.json endpoint
    const url = context.asPath + '/init-props.json';
    return fetch(url).then(response => {
      return response.json();
    });
  }
};

Saya dapat melihat keuntungan besar menggunakan metode getStaticProps dan getStaticPaths yang akan mengurangi banyak kode saya yang terkait dengan menyimpan file JSON dan memuatnya dari klien.

// pages/my_page.js
export async function getStaticProps(context) {
  const objects = await cmsSdkCient.getEntries();
  const props = _.find(object, { type: 'my_page' })
  return { props };
}

// pages/blog/[slug].js
export async function getStaticProps(context) {
  const objects = await cmsSdkCient.getEntries();
  const props = _.find(object, { type: 'post', slug: context.params.slug })
  return { props };
}

export async function getStaticPaths() {
  const objects = await cmsSdkCient.getEntries();
  return objects
    .filter(object => object.type === 'post')
    .map(object => ({ params: { slug: object.slug } }))
}

Apa yang mengganggu saya adalah pertanyaan bagaimana saya bisa mengoptimalkan alur kerja untuk membawa semua entri sekali, daripada mengambilnya setiap kali ketika getStaticProps atau getStaticPaths dipanggil?

Pertanyaan lain, mungkin belum tentu terkait dengan masalah ini, tetapi karena kita berada di dunia SSG dan sumber data jarak jauh, ada baiknya bertanya. Dengan asumsi next.js berjalan dalam mode dev, bagaimana seseorang dapat memberi tahu next.js untuk menjalankan kembali metode ini untuk mengambil kembali data jarak jauh dan membangun kembali situs.

@smnh Karena ini "hanya JavaScript", Anda dapat mengambil entri Anda sekali dan menyimpan hasil dalam metode pengambilan data Anda. Ketika dipanggil lagi di beberapa metode getStatic* halaman lain, jaringan tidak akan terkena lagi.

Adapun pertanyaan kedua Anda, ia melakukannya secara otomatis. Jalankan next dev dan Anda siap melakukannya.

Saya hanya melihat params jalur dalam contoh getStaticPaths atas. Apakah mungkin untuk jalur SSG yang menyertakan parameter kueri? Sebagai contoh:

/store/widgets/circles-n-squares?sort=price&minWeight=2&color=black

Saya terutama berpikir dari perspektif situs e-niaga, di mana akan sulit untuk mencakup setiap aspek pencarian produk di pathname dari sebuah url.

Saya tidak berpikir ini masuk akal dalam konteks ssg. SSG mengeluarkan file untuk setiap entri - parameter kueri bukan bagian dari nama file sehingga Anda memerlukan lapisan server untuk menulis ulang permintaan ke file yang sebenarnya. (Apa nama file statis Anda dalam contoh di atas?) Saya sarankan mempertimbangkan untuk melakukan prarender tampilan default (apa yang Anda dapatkan jika Anda mengunjungi halaman tanpa faset) dan memperbarui di sisi klien jika ada parameter kueri pada permintaan. Tapi itu menjadi masalah di luar RFC SSG ini.

@dpfavand saya juga mengalami hal yang sama! Mencoba membangun situs pemula untuk agilitycms dan nextjs dengan perutean halaman dinamis berdasarkan halaman di CMS.

@timneutkens terima kasih atas tindak lanjutnya. Saya sudah mencoba dua metode tanpa hasil. Pada dasarnya ketika menentukan nilai slug sebagai string dalam getStaticPaths , itu tidak diteruskan ke getStaticProps sama sekali.
Kasus 1, Dengan asumsi file pages/[...slug].jsx , slug sebagai string:

export async function unstable_getStaticPaths() {
    return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

Dalam kasus di atas, params di getStaticProps adalah objek kosong - tidak ada kunci slug .

BTW, dunia kecil! Sekali lagi terima kasih telah berbicara di fastr_conf.

Hai! Tim Nextjs mulai mengatasi ini, ada tiket terbuka untuk mengatasi beberapa masalah tambahan dengan implementasi canary saat ini: https://github.com/zeit/next.js/issues/10190

@smnh yang akhirnya saya lakukan adalah memiliki skrip yang mengambil terlebih dahulu konten yang dibagikan dan menyimpannya ke JSON sebelum menjalankan build + export. Kemudian Anda cukup mengimpor JSON itu langsung di halaman sebagai modul.

Untuk membangun kembali, saya telah menyiapkan webhook di CMS untuk memicu kait pembangunan Netlify ketika konten yang relevan berubah. GetStaticProps kemudian dapat mengambil konten khusus halaman.

Terima kasih @zeusdeux
Ulang:

Adapun pertanyaan kedua Anda, ia melakukannya secara otomatis. Jalankan dev berikutnya dan Anda siap melakukannya.

Jika saya cache dalam modul dan kemudian mengubah data dalam CMS, bagaimana cache akan dibatalkan dan dijalankan kembali oleh dev , tetapi tanpa berhenti next.js dan menjalankannya lagi :)

Jika saya cache dalam modul dan kemudian mengubah data dalam CMS, bagaimana cache akan dibatalkan dan dijalankan kembali oleh dev , tetapi tanpa berhenti next.js dan menjalankannya lagi :)

getStaticPaths hanya dipanggil di build produksi, jadi Anda hanya bisa memberi tahu metode pengambilan ke cache dalam status modul saat dipanggil dari fungsi itu.

Hei, saya belum melihat apakah ada orang yang mengalami masalah yang sama seperti saya.

Katakanlah saya memiliki halaman yang sama di beberapa rute dengan unstable_getStaticProps :

1. /providers/[category]/[city] 
2. /providers/[category] 

Kode sumber sama untuk kedua halaman sehingga tidak perlu diduplikasi. Jadi untuk file pertama berisi kode sumber dengan logika, yang kedua hanya mengimpor yang pertama seperti export { default } from './[city]'; .

Tapi itu menimbulkan kesalahan bahwa data dari getStaticProps tidak terdefinisi. Jika saya hardcopy kode yang sama ke kedua file itu berfungsi.

@homoky Anda perlu mengekspor kembali metode:

export { default, unstable_getStaticProps } from './[city]';

Saya telah mencoba SSG, tetapi tidak berhasil.

Haruskah kode di bawah ini dengan v9.2.1 menghasilkan SSG?

function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}

Page.unstable_getStaticProps = async ctx => {
  return { props: { stars: 5 } }
}

export default Page

Output konsol saya dari next build menunjukkan:

Page                                                           Size     First Load
┌ ○ /                                                          354 B       72.1 kB
...
λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

@joostmeijles unstable_getStaticProps perlu diekspor alih-alih dilampirkan ke komponen halaman, mis

export const unstable_getStaticProps = async () => {
  return {
    props: { stars: 5 }
  }
}

@joostmeijles unstable_getStaticProps perlu diekspor alih-alih dilampirkan ke komponen halaman, mis

export const unstable_getStaticProps = async () => {
  return {
    props: { stars: 5 }
  }
}

Terima kasih, itu menyelesaikannya.

Jika ada yang ingin melihat contoh kerja ujung ke ujung dari ini, membuat halaman dinamis (dari CMS) dengan rute catch-all dan SSG, periksa https://github.com/agility/agilitycms-next-starter- ssg.

Saya bingung beberapa kali dan berpikir ini bisa membantu orang lain.

Bagaimana saya bisa mengakses rute API berikutnya selama pembuatan dengan getStaticProps saat menerapkan di zeit.co/now? Pengambilan isomorfik membutuhkan URL absolut; secara lokal berfungsi dengan http://localhost :3000 tetapi tidak dengan penerapan sekarang (atau saya salah melakukannya ️). Ada ide?

Jika saya benar, rute API akan digunakan sebagai fungsi tanpa server dan saya rasa mereka belum siap selama proses pembuatan?

Anda akan ingin memanggil fungsi rute api Anda secara langsung karena overhead jauh lebih sedikit daripada melalui http.

Anda akan ingin memanggil fungsi rute api Anda secara langsung karena overhead jauh lebih sedikit daripada melalui http.

Adakah sumber daya yang dapat saya baca di dokumen tentang topik itu? Saya sedang dalam proses migrasi ke zeit.co/now :)

Secara harfiah, impor dan panggil fungsi:

import MyFunction from '../lib/somewhere'


export async function /* unstable_ */getStaticProps() {
  const result = await MyFunction()
}

Pertanyaan lain: Apakah mungkin menggunakan getStaticProps / getStaticPaths dan getServerProps berdampingan? Misalnya jika saya telah melakukan pra-render beberapa halaman dengan SSG, tetapi jika tidak ada yang ditemukan di cache CDN, maka itu akan mundur ke SSR untuk menghasilkan halaman sesuai permintaan?

getStaticProps akan mundur ke SSR dan menambahkan hasilnya ke cache,

getStaticProps akan mundur ke SSR dan menambahkan hasilnya ke cache,

@lfades , jika saya memahami Anda dengan benar, maka saya sangat 😍 tentang hal itu, karena itu berarti saya dapat melakukan pra-render beberapa halaman populer, alih-alih mencari dan menghasilkan beberapa ribu halaman sebelumnya.

Tapi hanya untuk memastikan saya mengerti... Katakanlah saya memiliki halaman jalur dinamis /products/[productId].js . Jika saya memberikan getStaticProps , dan sejumlah hasil terbatas dari getStaticPaths , maka Anda mengatakan jika /products/123 tidak ditemukan dalam cache CDN (karena tidak ditemukan) t di getStaticPaths ), itu akan turun kembali ke SSR, jalankan getStaticProps , dan kemudian cache hasilnya sebagai halaman statis?

Pertanyaan lanjutan: apakah itu juga berfungsi jika saya tidak memberikan getStaticPaths sama sekali?

@flintinatux Ya dan ya 👍

getStaticProps akan mundur ke SSR dan menambahkan hasilnya ke cache

Ini adalah masalah karena tidak ada cara untuk melakukan 404, karena getStaticProps tidak mengizinkan mengubah objek res - baik itu akan 200, atau 500 jika ada kesalahan selama pemanggilan fungsi.

Apakah ini direncanakan untuk berubah?

@davidbailey00 saat membuat situs web statis 404 halaman sudah tidak memiliki kode status 404.

Tentu saja jika saya melakukan ekspor statis penuh, tidak ada cara untuk melakukan kode status, karena semuanya hanyalah sebuah file. Saya sedang berbicara tentang menyebarkan situs hibrida menggunakan getStaticProps ke ZEIT Sekarang - sepertinya itu harus menghormati getStaticPaths dan melayani 404 halaman, daripada memaksa merender semua halaman yang cocok dengan jalur dinamis terlepas dari ini.

Itu bukan hanya cara kerjanya di Now, sama di next start .

Saya akan mengulangi seperti yang dikatakan sebelumnya: Ini eksperimental dan apa pun masih bisa berubah dalam perilaku.

Tapi itu mungkin untuk melayani 404 halaman dengan getServerProps atau getInitialProps - jika getStaticProps mengabaikan getStaticPaths ketika mempertimbangkan kode respons maka itu benar-benar tidak layak untuk situs mana pun yang peduli SEO yang bagus.

Kami mungkin akan memperkenalkan lebih banyak cara menangani kode status, tetapi perlu diingat bahwa sebagian besar situs statis (misalnya CRA) merutekan /* ke index.html mana 404 masih merupakan 200.

Hai teman-teman, saya punya pertanyaan langsung, saya sedang membangun situs web sederhana menggunakan [unstable_]getStaticProps untuk SSG beberapa halaman. Semua itu berfungsi dengan baik sejauh ini, kecuali amp .

Jika halaman berisi [unstable_]getStaticProps , maka amp dinonaktifkan. Berikut contoh sederhana yang bekerja dengan v9.2.1 berikutnya di mana Anda dapat memeriksanya:

import React from "react";
import { useAmp } from "next/amp";

export const config = { amp: `hybrid` };

const AmpExample = ({ date }) => {
  const isAmp = useAmp();
  return (
    <>
      <p>
        Welcome to the {isAmp ? `AMP` : `normal`} version of the Index page!!
      </p>
      <p>date: {date}</p>
    </>
  );
};
/**
 * If I get the dynamic data from getStaticProps,
 * page is SSG render but AMP is disabled when accessing
 * with `/ampExample?amp=1`
 */
export async function unstable_getStaticProps() {
  return {
    props: {
      date: new Date().toISOString(),
    },
  };
}

/**
 * If I get the dynamic data from getInitialProps,
 * page is SSR render but AMP is disabled when accessing
 * with `/ampExample?amp=1`
 */
// AmpExample.getInitialProps = () => {
//   return { date: new Date().toISOString() }
// }
export default AmpExample;

Adakah bantuan untuk memahami cara agar halaman SSG dengan data dan amp berfungsi?

Hai, bagaimana dengan mendukung getStaticProps untuk komponen App ( _app.tsx ) yaitu untuk kasus seperti mengambil data umum untuk semua komponen halaman selama tahap pembuatan?

Hai, bagaimana dengan mendukung getStaticProps untuk komponen App ( _app.tsx ) yaitu untuk kasus seperti mengambil data umum untuk semua komponen halaman selama tahap pembuatan?

@ pkral78 Saya dapat memberi tahu Anda bagaimana saya menyelesaikan dengan keadaan pengembangan yang sebenarnya.

Saya membuat Layout dengan pendekatan "Layout as a Higher Order Component (HOC)" (tidak ada lagi di dokumen pembelajaran ️).

Bagaimanapun, saya membuat Layout seperti berikut (hanya sebagai contoh):

import React from "react";
import Head from "next/head";

const withSSGLayout = Page => {
  const WithSSGLayout = props => {
    return (
      <>
        <Head>
          <title>My Web Page</title>
          <link rel="icon" href="/favicon.ico" />
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          <link
            href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"
            rel="stylesheet"
          />
        </Head>
        <Page {...props} />
      </>
    );
  };

  WithSSGLayout.unstable_getStaticProps = async () => {
    const pageStaticProps = Page.unstable_getStaticProps
      ? await Page.unstable_getStaticProps()
      : {};

    // Here you can make parent level queries too
    return {
      props: {
        ...pageStaticProps.props,
        parentProp: `dynamic prop-${new Date().toISOString()}`,
      },
    };
  };
  return WithSSGLayout;
};

export default withSSGLayout;

Dan kemudian di halaman yang ingin Anda gunakan pendekatan ini, Anda dapat dengan mudah menambahkan HOC (Anda harus secara eksplisit mengekspor [unstable_]getStaticProps dan amp tidak bekerja bersama), tetapi saya menemukan "cara yang bagus" untuk memiliki permintaan tingkat tinggi dan kueri SSG per halaman.

import React from "react";
import withSSGLayout from "../hocs/withSSGLayout";

export const config = { amp: `true` };

const Index = props => {
  const { date, parentProp } = props;
  return (
    <div>
      <h1>Example</h1>
      <h3>Local Prop?: {date}</h3>
      <h3>Parent Prop?: {parentProp}</h3>
    </div>
  );
};

// In theory you could do direct database queries
Index.unstable_getStaticProps = async () => {
  // Here you can make page level queries
  return {
    props: {
      date: new Date().toISOString(),
    },
  };
};
const IndexHOC = withSSGLayout(Index);

export const { unstable_getStaticProps } = IndexHOC;
export default IndexHOC;

Ingin curang jika itu pendekatan yang baik. Dalam kasus saya, saya menggunakan teknik ini untuk menanyakan tautan di induk dan konten per halaman di halaman. Saya harap ini membantu.

@robertovg Anda harus mengekspor pada level modul karena kodenya diguncang pohon. Cara Anda memodelkannya menyebabkan lebih banyak kode dikirimkan ke sisi klien.

@timneutkens Bisakah Anda mengusulkan solusi yang lebih baik untuk contoh kecil ini ? Saya hanya mencoba untuk memiliki "kueri SSG tingkat tata letak" dan "kueri SSG Tingkat Halaman" dalam beberapa cara dan saya memikirkan pendekatan Tata Letak HOC ini.

Kendala utama bagi saya adalah secara eksplisit "mengekspor [unstable_]getStaticProps" yang harus Anda miliki di setiap halaman untuk ditandai sebagai halaman SSG.

Saya juga sangat menghargai beberapa info lebih lanjut tentang apakah amp + SSG akan kompatibel, saya bertanya sebelumnya.

Terima kasih 🙏

@robertovg Pertama, Pisahkan Tata Letak dari data, jadi untuk Tata Letak yang dibagikan Anda akan memiliki sesuatu yang sederhana seperti ini:

import Layout from '../components/layout'

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

Dan kemudian untuk getStaticProps ambil data bersama menggunakan metode dari modul lain, sehingga contoh lengkapnya bisa terlihat seperti:

import fetchSharedData from '../lib/fetch-shared-data'
import Layout from '../components/layout'

export const unstable_getStaticProps = async () => {
  const sharedData = await fetchSharedData()
  const pageProps = {...}

  return {  props: { ...sharedData, ...pageProps } }
}

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

@robertovg Pertama, Pisahkan Tata Letak dari data, jadi untuk Tata Letak yang dibagikan Anda akan memiliki sesuatu yang sederhana seperti ini:

import Layout from '../components/layout'

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

Dan kemudian untuk getStaticProps ambil data bersama menggunakan metode dari modul lain, sehingga contoh lengkapnya bisa terlihat seperti:

import fetchSharedData from '../lib/fetch-shared-data'
import Layout from '../components/layout'

export const unstable_getStaticProps = async () => {
  const sharedData = await fetchSharedData()
  const pageProps = {...}

  return {  props: { ...sharedData, ...pageProps } }
}

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

Saya melihat dan saya memahami solusi ini tetapi masalah yang saya coba kemukakan adalah bagaimana menskalakan penggunaan data bersama.
Misalnya, jika Anda memiliki <Header /> yang menggunakan sharedData untuk mendapatkan tautan dan tautan tersebut berasal dari CMS Tanpa Kepala. Anda harus menyuntikkan <Header /> sebagai anak dari <Layout /> dengan alat peraga atau solusi lain. Dan Anda perlu mengulangi injeksi <Header /> ke semua halaman yang ingin Anda gunakan.

Dengan pendekatan HOC Anda cukup menambahkan <Header /> sekali di HOC.

Itu sebabnya saya pikir itu adalah poin bagus yang diangkat oleh @pkral78 , untuk menghindari duplikasi kode jika memungkinkan.

Itu sebabnya saya pikir itu adalah poin bagus yang diangkat oleh @pkral78 , untuk menghindari duplikasi kode jika memungkinkan.

Itu ada di pikiran saya. Halaman _app harus memiliki getStaticProps yang dipanggil sekali selama render halaman pertama dan kemudian meneruskan props disimpan ke halaman render berikutnya. Tapi saya masih berpikir apakah itu konsep yang tepat.

Tidak yakin apakah hal semacam ini adalah kasus penggunaan yang dimaksudkan, tetapi tampaknya tidak berhasil:

// /pages/[...slug].jsx
import ReactDOMServer from "react-dom/server";

export async function unstable_getStaticProps({ params: { slug } }) {
  const filePath = "../content/" + slug.join("/") + ".mdx";
  const { default: Component } = await import(filePath);
  const content = ReactDOMServer.renderToStaticMarkup(<Component />);
  return {
    props: { title: slug.join(" "), content }
  };
}

export default function Page({ title, content }) {
  return (
    <div>
      <h1>{title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </div>
  );
}

Bahkan jika itu bukan kasus penggunaan yang dimaksudkan, itu mencatat kesalahan yang tampaknya agak mencurigakan:

[ warn ]  ./pages/[...slug].jsx
Critical dependency: the request of a dependency is an expression

Sunting:

Oh, ok, itu akan teratasi ketika saya melakukannya

const { default: Component } = await import(`../content/${slug.join("/")}.mdx`);

https://codesandbox.io/s/happy-oskar-40bug

Ini mengeluh tentang jalur file impor Anda yang dinamis

Pada Kamis, 30 Jan 2020 pukul 00:29, Jan Potoms [email protected] menulis:

Tidak yakin apakah hal semacam ini
https://codesandbox.io/s/nifty-cache-jspqr adalah kasus penggunaan yang dimaksudkan, tetapi
sepertinya tidak berhasil:

// /pages/[...slug].jsximport ReactDOMServer dari "react-dom/server";
ekspor fungsi async stable_getStaticProps({ params: { slug } }) {
// seberapa amankah ini?
const filePath = "../content/" + slug.join("/") + ".mdx";
const { default: Komponen } = menunggu impor(filePath);
const konten = ReactDOMServer.renderToStaticMarkup(Komponen);
kembali {
alat peraga: { judul: slug.join(""), konten }
};
}
ekspor fungsi default Halaman({ judul, konten }) {
kembali (


{judul}




);
}

Bahkan jika itu bukan kasus penggunaan yang dimaksudkan, itu mencatat kesalahan yang tampaknya
agak mencurigakan:

[ peringatkan ] ./pages/[...slug].jsx
Ketergantungan kritis: permintaan ketergantungan adalah ekspresi


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AAADKRKOL34WKTG7J5QFRJ3RAIGPBA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTOR5JWSY27
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AAADKRIWNA2DSMWFRGD453DRAIGPBANCNFSM4JRPBELQ
.

Itu sebabnya saya pikir itu adalah poin bagus yang diangkat oleh @pkral78 , untuk menghindari duplikasi kode jika memungkinkan.

Itu ada di pikiran saya. Halaman _app harus memiliki getStaticProps yang dipanggil sekali selama rendering halaman pertama dan kemudian meneruskan props disimpan ke halaman render berikutnya. Tapi saya masih berpikir apakah itu konsep yang tepat.

@pkral78 , Bisa jadi karena di sebagian besar situs SSG yang saya bayangkan diimplementasikan dengan Berikutnya, saya ingin memiliki "bagian umum" (Header, Footer, Side Bar...). Dan mengapa tidak membuat kueri untuk bagian umum itu di _app jika Anda perlu, dan membuatnya tersedia di halaman anak tanpa harus secara manual di setiap halaman.

Satu-satunya kekhawatiran saya adalah jika Anda memasukkannya ke dalam _app.js , kami tidak dapat memiliki lebih dari satu "bagian umum" tergantung pada halaman. Dengan ide saya membuat prototipe, saya ingin dapat memilikinya di Tata Letak karena itu akan memungkinkan kita untuk memiliki beberapa Tata Letak tergantung pada jenis halaman yang ingin Anda render, "itu sebabnya saya menelepon withSSGLayout untuk HOC saya karena saya berencana untuk tidak hanya memiliki halaman SSG tetapi SSR dan sepenuhnya berbasis klien, atau bahkan lebih dari satu SSGLayout. Saya ini dapat dilakukan jika Layouts juga dapat bertanggung jawab atas metode getStaticProps induk.

Bagaimanapun, memiliki SSG di Next akan menjadikannya alat untuk semua jenis situs web

@Janpot berkaitan dengan https://github.com/zeit/next.js/issues/9524#issuecomment -580012327

Sangat merekomendasikan untuk tidak pernah menggunakan jalur dinamis di import() . Ini akan menggabungkan setiap file yang mungkin di bawah jalur ke dalam bundel JS dan sangat mengurangi kinerja build dalam melakukannya.

@timneutkens Tentu, masuk akal. Apakah getStaticProps hanya dimaksudkan untuk menanyakan API eksternal, bukan sistem file?

@Janpot Anda dapat membaca dari sistem file, seringkali Anda akhirnya akan menanyakan beberapa API eksternal.

@timneutkens Ok, lebih baik menggunakan @mdx-js/runtime daripada mengandalkan @next/mdx kurasa.

import ReactDOMServer from "react-dom/server";
import { promises as fs } from "fs";
import MDX from "@mdx-js/runtime";

export async function unstable_getStaticProps({ params: { slug } }) {
  const mdxContent = await fs.readFile(`./content/${slug.join('/')}.mdx`, {
    encoding: "utf-8"
  });
  const content = ReactDOMServer.renderToStaticMarkup(<MDX>{mdxContent}</MDX>);
  return {
    props: { title: slug.join(" "), content }
  };
}

export default function Page({ title, content }) {
  return (
    <div>
      <h1>{title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </div>
  );
}

@Janpot ya! anda juga bisa menggunakan penurunan harga biasa, itulah yang kami lakukan untuk nextjs.org/docs.

Mengenai https://github.com/zeit/next.js/issues/9524#issuecomment -580207073 , persis seperti saat ini saya menggunakan Next dengan SSR. Saya memiliki permintaan GraphQL yang dilakukan di tingkat Tata Letak, dan kontennya dibagikan dengan komponen umum aplikasi (Navbar, Footer, dan anak-anak dinamis). Kemudian, anak-anak dinamis biasanya membuat permintaan GraphQL lain untuk konten khusus halaman.

Jadi, memiliki cara untuk menggunakan kembali ini tampaknya penting, saya tidak ingin harus menduplikasi kode pada setiap halaman untuk mengambil data umum tersebut.

Hai!
Saya cukup baru di sini. Baru mulai mengerjakan migrasi aplikasi ke NextJS.

Ada kasus penggunaan dasar yang akan sangat diuntungkan dari fitur ini - beberapa versi bahasa. Aplikasi web yang saya kerjakan memiliki 16 versi bahasa dengan 100.000+ tampilan halaman sehari dan hanya dapat menghasilkan secara statis misalnya halaman arahan akan menjadi fantastis tetapi masalahnya adalah perutean.

Dengan rendering sisi server, saya dapat membaca header atau cookie permintaan dan membuat versi bahasa yang tepat tetapi tanpa itu, apakah satu-satunya solusi untuk membuat jalur untuk setiap versi seperti /en, /de, /fr dan pada "/" membuat NextJS hanya mengarahkan ulang?

Setelah mempelajari tentang ReactDOMServer.renderToStaticMarkup saya menambahkannya ke fungsi unstable_getStaticProps saya dan ternyata itu meningkatkan skor PageSpeed ​​(seluler) saya dari 96 menjadi 100 berkat peningkatan Waktu untuk Interaktif dan Potensi Maksimum First Input Delay secara drastis .

Saya dapat mengunjungi halaman tanpa JavaScript dan memuat dengan baik, jadi tampaknya React bekerja pada pemuatan halaman, meskipun menggunakan SSG.

Mungkin ini adalah kurangnya pemahaman saya tentang Bereaksi, tetapi saya berharap kinerja dengan dan tanpa JavaScript akan sama, dan saya tidak mengharapkan pra-rendering komponen untuk membantu (saya pikir itulah yang dilakukan SSG).

Apakah yang diharapkan, bug, atau sesuatu yang saya lakukan salah?

Pra-komitmen: https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2F5e310826bcf5030008a91209--josephduffynextjs.netlify.com%2Fposts%2Fgathered-1-0-1&tab=mobile
Komit: https://github.com/JosephDuffy/josephduffy.co.uk/pull/54/commits/d23898b874e5088ebcfabf577ee396b476ed97e4
Pasca-komit: https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2F5e3371beda1b8f0009368ef9--josephduffynextjs.netlify.com%2Fposts%2Fgathered-1-0-1&tab=mobile

@JosephDuffy

jadi tampaknya React bekerja pada pemuatan halaman, meskipun menggunakan SSG.

Ini menghidrasi DOM. Pada dasarnya:

  1. browser Anda memuat html SSR di browser DOM
  2. React membangun kembali seluruh DOM virtual
  3. React melintasi DOM ini dan menyinkronkannya (hidrasi)

Jika konten Anda benar-benar statis, seperti tanpa efek samping atau event handler, maka langkah 2. dan 3. agak tidak perlu. Dengan metode Anda, pada dasarnya Anda mengurangi pohon komponen menjadi 1 komponen dengan 1 atribut, yang sangat cepat bagi React untuk merender dan menghidrasi. (+ dangerouslySetInnerHTM diabaikan selama hidrasi)

<div dangerouslySetInnerHTML={{ __html: props.htmlContent }} />

Perlu diingat bahwa event handler dan efek samping tidak akan bekerja dengan metode ini.

Sunting:

Satu ide adalah mengizinkan untuk menghilangkan ekspor default pada halaman jika getStaticProps mengembalikan html statis. yaitu

export async function unstable_getStaticProps() {
  // ...
  return {
    props: { dangerouslySetInnerHTML: { __html: '<div>static content</div>' } }
  };
}

Karena tidak ada yang perlu dirender dari sisi klien, next.js dapat mengecualikan runtime-nya dari halaman dan hanya memasukkan html yang dikembalikan getStaticProps . Dan itu akan bekerja dengan cara yang sama seperti jika dangerouslySetInnerHTML digunakan pada simpul akar next.js.
Saya kira itu akan lebih mudah diterapkan daripada hidrasi parsial, meskipun kurang kuat. Menggunakan kembali terminologi React sendiri di sini dapat mengurangi kebingungan tentang cara kerja fitur ini.

Saya mencoba memigrasikan situs statis ke Next.js dan saya ingin mengalihkan semua varian .html dari posting blog ke versi yang tidak berakhiran .html. Sepertinya getStaticProps saat ini tidak mendapatkan konteks jadi saya tidak dapat melakukan pemeriksaan untuk slug dan redirect yang masuk. Akan sangat membantu jika getStaticProps mendapatkan konteks penuh sehingga saya dapat melakukan beberapa hal bersyarat dengannya.

@nodabladam sepertinya Anda sedang mencari Rute Kustom RFC: #9081.

RFC itu akan memungkinkan Anda untuk mendefinisikan sesuatu seperti ini:

// next.config.js
module.exports = {
  redirects() {
    return [
      // Redirect from the old HTML version of a blog post
      {
        source: "/blog/:post.html",
        destination: "/blog/:post",
        permanent: true
      }
    ];
  }
};

Saat ini Anda dapat mencoba fitur ini di bawah kunci experimental :

// next.config.js
module.exports = {
  experimental: {
    redirects() {
      // ...
    }
  }
};

Saya telah menerapkan getStaticProps dan getStaticPathNames pada proyek saya (sekitar 8 ribu halaman).

Namun file keluaran dihitung dalam batas 10 ribu file per penerapan. Dengan 8K halaman Anda mendapatkan 16K file output karena setiap halaman juga mendapatkan file json.

Apakah ada rencana untuk meningkatkan batas ini? Atau bisakah saya mengatasi batas ini?

Saya memiliki masalah yang sama.
Saya mengerti mereka ingin mengangkat batas itu, tetapi saya tidak tahu kapan itu akan diterapkan.

Jadi saya menggunakan getStaticProps di semua halaman dan getStaticPaths hanya pada beberapa di antaranya dan berhasil (halaman produk saya menghasilkan 70% dari total halaman jadi saya tidak memasukkan getStaticPaths di dalamnya). Saya tetap di bawah batas tetapi tidak sempurna, pemuatan pertama cukup lama dan sulit untuk menangani 404 kesalahan.

Saya memiliki masalah yang sama.
Saya mengerti mereka ingin mengangkat batas itu, tetapi saya tidak tahu kapan itu akan diterapkan.

Jadi saya menggunakan getStaticProps di semua halaman dan getStaticPaths hanya pada beberapa di antaranya dan berhasil (halaman produk saya menghasilkan 70% dari total halaman jadi saya tidak memasukkan getStaticPaths di dalamnya). Saya tetap di bawah batas tetapi tidak sempurna, pemuatan pertama cukup lama dan sulit untuk menangani 404 kesalahan.

Saya harap mereka segera menaikkan batasnya, namun saya harap itu tidak akan menjadi 20K .. itu tidak akan cukup bagi saya dalam jangka panjang.

Saya ingin menghindari waktu pemuatan pertama dengan getStaticPaths.. Saya mungkin harus mencari solusi lain selain Zeit Now

Next.js juga akan secara otomatis mengekspos titik akhir API yang mengembalikan hasil pemanggilan getServerProps. [...] Next.js akan mengambil titik akhir API yang terbuka ini untuk mendapatkan data JSON yang diubah menjadi alat peraga yang diperlukan untuk merender halaman sisi klien.

Next.js akan mengambil data dari titik akhir ini sebelum melakukan perubahan rute aktual dan merender komponen halaman (setidaknya secara default, tidak dapat melakukannya dengan cara lain). Jadi pengguna mungkin mengalami situs yang sangat tajam karena halaman tertentu dibuat secara statis, tetapi jika mereka mengklik tautan ke halaman SSR, tiba-tiba situs akan "hang" beberapa saat sebelum rute berubah.

Apakah ada cara yang disarankan untuk memuat komponen _first_ sehingga dapat diisi dengan indikator pemuatan, placeholder animasi, dll? (Alih-alih menambahkannya ke halaman saat ini.) Jika tidak, apakah itu relevan dengan fitur yang baru diusulkan? Saya mencapainya menggunakan kombinasi getInitialProps dan kait di dalam metode render, tetapi rasanya berantakan.

Saya akan berpikir pola UX ini (pengalihan halaman instan) lebih disukai oleh banyak (kebanyakan?), Tetapi saya belum melihat contohnya menggunakan Next.js. Saya hanya menggunakan kerangka kerja selama beberapa hari, jadi tolong perbaiki saya jika saya salah.

Sangat bersemangat tentang fitur-fitur baru! Terima kasih atas pekerjaan Anda.

@nicoqh , kekhawatiran Anda tentang transisi halaman tidak khusus untuk SSG, karena hang terjadi dengan getInitialProps . Saya menggunakan nprogress untuk setidaknya menampilkan bilah kemajuan di atas saat halaman berikutnya sedang dimuat, tetapi saya juga melihat contoh transisi halaman yang sah yang terdengar lebih dekat dengan apa yang Anda gambarkan. Saya belum mencobanya sendiri, tetapi saya harap ini membantu dengan apa yang Anda butuhkan:
https://github.com/zeit/next.js/tree/canary/examples/with-next-page-transitions

Sepertinya file json /_next/data/BUILD_ID/<file>.json yang dikembalikan tidak menghormati assetPrefix. Ini menyebabkan file menjadi 404 untuk saya di lingkungan produksi saya karena saya memiliki pengaturan yang mengharapkan semuanya _next menjadi aset yang melewati CDN. File json ini pada akhirnya harus merutekan melalui assetPrefix (CDN) bukan?

Saya memiliki masalah yang sama.
Saya mengerti mereka ingin mengangkat batas itu, tetapi saya tidak tahu kapan itu akan diterapkan.
Jadi saya menggunakan getStaticProps di semua halaman dan getStaticPaths hanya pada beberapa di antaranya dan berhasil (halaman produk saya menghasilkan 70% dari total halaman jadi saya tidak memasukkan getStaticPaths di dalamnya). Saya tetap di bawah batas tetapi tidak sempurna, pemuatan pertama cukup lama dan sulit untuk menangani 404 kesalahan.

Saya harap mereka segera menaikkan batasnya, namun saya harap itu tidak akan menjadi 20K .. itu tidak akan cukup bagi saya dalam jangka panjang.

Saya ingin menghindari waktu pemuatan pertama dengan getStaticPaths.. Saya mungkin harus mencari solusi lain selain Zeit Now

@erhankaradeniz dan @ziltosh kita harus segera meluncurkannya secara umum. Jika Anda ingin mendapatkan bantuan secepatnya, Anda dapat melakukan ping ke saya secara langsung atau [email protected] dan mereka akan menyelesaikan masalah Anda.

Saya memiliki masalah yang sama.
Saya mengerti mereka ingin mengangkat batas itu, tetapi saya tidak tahu kapan itu akan diterapkan.
Jadi saya menggunakan getStaticProps di semua halaman dan getStaticPaths hanya pada beberapa di antaranya dan berhasil (halaman produk saya menghasilkan 70% dari total halaman jadi saya tidak memasukkan getStaticPaths di dalamnya). Saya tetap di bawah batas tetapi tidak sempurna, pemuatan pertama cukup lama dan sulit untuk menangani 404 kesalahan.

Saya harap mereka segera menaikkan batasnya, namun saya harap itu tidak akan menjadi 20K .. itu tidak akan cukup bagi saya dalam jangka panjang.
Saya ingin menghindari waktu pemuatan pertama dengan getStaticPaths.. Saya mungkin harus mencari solusi lain selain Zeit Now

@erhankaradeniz dan @Ziltosh kita harus segera meluncurkannya secara umum. Jika Anda ingin mendapatkan bantuan secepatnya, Anda dapat melakukan ping ke saya secara langsung atau [email protected] dan mereka akan menyelesaikan masalah Anda.

Terima kasih @kvangundy
Saya telah menghubungi Anda di Twitter mengenai masalah ini ;-)

@erhankaradeniz Bisakah Anda mengirim email ke [email protected] ? Dengan cara itu berakhir di sistem kami dengan benar.

@flintinatux , terima kasih atas tipnya. Saya telah melihat contohnya, dan itu tidak membantu memuat komponen halaman sebelum memuat data, jadi placeholder dalam halaman dll. tidak mungkin. Ini adalah contoh yang menarik, terima kasih!

Saya kira itu tidak akan dibahas dalam masalah ini, yang berarti di luar topik, jadi saya akan mencari tempat lain untuk membahasnya :)

Saya pikir pendekatan memecah getInitialProps menjadi getStaticProps & getServerProps jauh lebih bersih! Saya punya pertanyaan tentang bagaimana ini memengaruhi kasus penggunaan kami:
Kami ingin membuat 2 build terpisah: satu versi statis untuk situs prod kami, dan satu versi menggunakan SSR untuk lingkungan pengeditan.

Saya berpikir saya dapat melampirkan getStaticProps vs getServerProps secara kondisional sebagai metode statis tergantung pada build (mirip dengan https://github.com/zeit/next.js/issues/9524#issuecomment- 558617056), tetapi saya tidak yakin apakah ini mungkin untuk mengekspornya secara kondisional apa adanya. Adakah ide jika ini memungkinkan untuk mendukung dinamis/statis tergantung pada build?

Berkaitan dengan:

RFC akan diperbarui untuk mencerminkan perubahan nanti, masih mengulangi penggunaan dunia nyata di aplikasi kami.

Saya ingin tahu apakah ada cara untuk menggunakan semacam rute wildcard untuk menangkap rute yang tidak diketahui pada waktu pembuatan. Luar biasa bahwa saya dapat merender halaman statis dari misalnya data CMS, tetapi bagaimana jika seseorang menambahkan item baru? Saya tidak memiliki halaman statis untuk itu. Masalah ini menggaruk kepalaku untuk waktu yang lama.

Saya telah menyiapkan rute dinamis untuk merender halaman statis _pages/[slug].js_. _getStaticPaths_ mendapatkan semua halaman yang ingin saya render secara statis. Saya memiliki _getStaticProps_ untuk menanyakan data dan meneruskannya ke fungsi render. Semua halaman yang diberikan di _getStaticPaths_ dirender sebagai file HTML di dalam _.next/server/static_ saat dibuat. Besar!

Sekarang saya menjalankan npm run start dan halaman-halaman ini sebagaimana mestinya. Tetapi meminta url yang hilang (seperti _/foo_) menghasilkan file HTML dan JSON statis baru di dalam _.next/server/static_. Ini tidak bagus. Bagaimana saya bisa membuat server mengarahkan semua url lain ke _pages/_error.js_?

https://github.com/zeit/next.js/issues/9524#issuecomment -582777067

Kami juga menutupinya.

Sekarang saya menjalankan npm run start dan halaman-halaman ini sebagaimana mestinya. Tetapi meminta url yang hilang (seperti /foo) menghasilkan file HTML dan JSON statis baru di dalam .next/server/static. Ini tidak bagus. Bagaimana saya bisa membuat server mengarahkan semua url lain ke halaman/_error.js?

Ini masih dalam penerbangan dan bukan perilaku yang tidak terduga untuk saat ini.

Sekali lagi pengingat bahwa Anda menggunakan fitur eksperimental dan perilaku dapat berubah kapan saja. Hal-hal akan berubah dan berpotensi pecah di antara semua versi saat Anda menggunakan ini saat tidak stabil.

@timneutkens Terima kasih! Saya memahami ketidakstabilan. Apakah Anda tahu bagaimana mengelola ini? Pergi melalui kode dan perhatikan bahwa melempar kesalahan di dalam _unstable_getStaticProps_ membuat halaman kesalahan. Ini bisa menjadi cara yang bagus. Saya hanya perlu cara untuk meneruskan kesalahan seperti ke _pages/_error.js_. Saya ingin mengirimkannya 404. Sekarang menjadi 500.

Saya telah memposting ini beberapa kali sebelumnya di utas lain, tetapi "akan _error" adalah perilaku yang tidak terduga, mulai sekarang halaman Anda harus membuat status 404. Cukup katakan if(!data.something) { return <My404Component /> } , dan kemudian My404Component harus menetapkan tag meta noindex .

Betulkah? Dokumentasi dengan jelas menginstruksikan untuk menggunakan _pages/_error.js_ selama 404 detik.

Lihat: https://nextjs.org/docs/advanced-features/custom-error-page

@jiv-e itu untuk 404 yang disebabkan oleh:

  • halaman tidak ditemukan
  • Berkas tidak ditemukan

Jika Anda memiliki rute dinamis, Anda harus menangani kasus "404" seperti yang saya katakan, misalnya seperti https://nextjs.org/docs/advanced-features/custom-error-page#reusing -the-built-in-error- halaman

Mengerti! Terima kasih!

Saya ingin menggunakan getStaticProps untuk mengambil terjemahan / kunci bahasa pada waktu pembuatan karena kemungkinan besar akan berubah 1-2 kali sebulan atau bahkan per tahun. Juga juga tidak membutuhkannya sebagai JSON/alat peraga dalam DOM. Masalahnya adalah saya tidak ingin memberikan kunci ke bawah pohon ke komponen tempat saya benar-benar menggunakannya - Pendekatan apa yang cocok untuk kasus penggunaan saya?

useTranslation() kait (atau HOC) dengan konteks?

Akan lebih baik jika AppTree akan menjadi bagian dari Konteks NextGetStaticProps ( getStaticProps({ AppTree }) ). Kalau tidak, tidak mungkin menjalankan hal-hal seperti apollos getDataFromTree di ssg.

Pada titik ini kami tidak berencana untuk mengizinkan traversal AppTree di getStaticProps karena sangat buruk untuk kinerja (umpan balik yang konsisten dari perusahaan). Saat Anda menambahkan getStaticProps ke halaman, itu masih melalui getInitialProps dari _app untuk memungkinkan adopsi tambahan, jadi itu masih akan bekerja dengan Apollo.

Alangkah baiknya jika kita bisa memiliki fungsi amp: 'hybrid' dan SSG secara bersamaan.
Ini dapat dicapai dengan membuat dua file untuk halaman seperti ini, yaitu:

  • (SSG) index.html
  • (AMP) index.amp.html

Ini akan memungkinkan proxy untuk menyelesaikan ke dokumen amp berdasarkan parameter kueri ?amp=1 .

Alangkah baiknya jika kita bisa memiliki fungsi amp: 'hybrid' dan SSG secara bersamaan.
Ini dapat dicapai dengan membuat dua file untuk halaman seperti ini, yaitu:

  • (SSG) index.html
  • (AMP) index.amp.html

Ini akan memungkinkan proxy untuk menyelesaikan ke dokumen amp berdasarkan parameter kueri ?amp=1 .

Persis @Dacturne , ini adalah satu-satunya downside yang saya lihat untuk mulai menggunakan SSG pada proyek seperti yang saya komentari di utas ini beberapa waktu lalu.

🤞

@jansedlon Saya telah membuat posting blog dan menjawab pertanyaan Anda:

Saya ingin tahu apakah ada cara untuk menggunakan semacam rute wildcard untuk menangkap rute yang tidak diketahui pada waktu pembuatan. Luar biasa bahwa saya dapat merender halaman statis dari misalnya data CMS, tetapi bagaimana jika seseorang menambahkan item baru? Saya tidak memiliki halaman statis untuk itu. Masalah ini menggaruk kepalaku untuk waktu yang lama.

https://paqmind.com/en/blog/ssr-is-not-the-future

(tidak memposting di sini karena terlalu besar)

@ivan-kleshnin Saya telah melihat sekilas dan terlihat sangat menarik! Anda mungkin telah menyelamatkan saya ratusan jam! Terima kasih banyak, saya akan melihat lebih mendalam nanti hari ini.

https://github.com/zeit/next.js/issues/9524#issuecomment -582799948

@jansedlon seperti yang dikatakan sebelumnya, kami sedang mengerjakan sesuatu sehubungan dengan ini yang tidak tercakup dalam posting blog @ivan-kleshnin. Semoga bisa berbagi lebih banyak tentang ini segera.

@timneutkens Suka perubahan sejauh ini 🙏 Apakah Anda punya rencana untuk meningkatkan/mendukung internasionalisasi+statis penuh?

Kami telah menggunakan getStaticProps / getStaticPaths API baru dalam migrasi tinacms.org dari Gatsby ke Next.js, dan sejauh ini luar biasa!

Satu batu sandungan yang kami alami adalah dalam menghasilkan umpan RSS. Idealnya kami ingin membuatnya secara statis, karena konten yang dirujuknya dibuat secara statis. Saya tidak melihat cara untuk melakukan ini saat ini, jadi alih-alih kami hanya menanganinya di sisi server dengan menanyakan konten dan menulis XML ke respons.

Apakah ada diskusi tentang mendukung pembuatan statis untuk jenis konten non-HTML?

FYI Kami mulai menggunakan getStaticProps pada zeit sekarang dan rilis menggunakan flag --prod dan cache tidak dibersihkan untuk file json pada rilis baru. Mengalihkan rilis produksi kami kembali menggunakan fitur alias berhasil dan cache dihapus.

Kami telah menggunakan getStaticProps / getStaticPaths API baru dalam migrasi tinacms.org dari Gatsby ke Next.js, dan sejauh ini luar biasa!

Satu batu sandungan yang kami alami adalah dalam menghasilkan umpan RSS. Idealnya kami ingin membuatnya secara statis, karena konten yang dirujuknya dibuat secara statis. Saya tidak melihat cara untuk melakukan ini saat ini, jadi alih-alih kami hanya menanganinya di sisi server dengan menanyakan konten dan menulis XML ke respons.

Apakah ada diskusi tentang mendukung pembuatan statis untuk jenis konten non-HTML?

Saya memikirkannya sendiri dan saya baru tahu ini. Berikut adalah skrip saya:

"scripts": {
    "dev": " next",
    "build": "yarn sitemap && next build",
    "start": "next start",
    "sitemap": "ts-node --project ./cli/tsconfig.spec.json ./cli/generateSitemap.ts"
  },

Sebelum next build disebut yarn sitemap yang menghasilkan peta situs statis. Anda dapat menggunakan teknik yang sama, untuk men-cache semua data ke json misalnya, yang Anda perlukan di getStaticProps dan Anda dapat menggunakannya kembali di beberapa halaman.

Memperbarui RFC, mengubah perilaku getStaticPaths sedikit (Anda perlu mengembalikan kunci paths sekarang, ini mencerminkan getStaticProps mana props harus dikembalikan. Ini perubahan belum mendarat di Next.js.

Juga menambahkan penjelasan untuk perilaku fallback (pembuatan halaman latar belakang sesuai permintaan yang tidak diekspor pada waktu pembuatan).

Melakukan pembaruan lain ke RFC, menambahkan penjelasan untuk perubahan dalam navigasi klien sehubungan dengan status Loading .

Kami mungkin ingin menambahkan cara bagi pengguna untuk mengetahui apakah status pemuatan sedang dirender melalui kait Bereaksi

Barang bagus! Saya hanya ingin tahu, apakah ada cara bagi halaman yang dibuat secara statis untuk berbagi data di antara beberapa rute menggunakan satu file JSON (seperti pemecahan kode tetapi untuk data)?

Saya bertemu dengan versi canary dan segera digigit oleh status Loading . Di masa lalu, bagus untuk berasumsi dengan aman bahwa saya sudah mendapatkan data yang benar sebelum lapisan tampilan mulai dirender. Pemuatan asinkron paksa adalah penyimpangan besar dari itu. Saya benar-benar menikmati merobek semua titik akhir boilerplate yang akan diganti oleh titik akhir SSR yang dihasilkan secara otomatis, tetapi saya tidak berencana untuk mendesain ulang setiap halaman untuk menyertakan status Loading .

Saya memahami keinginan untuk TTFB yang lebih cepat, dan di masa depan yang mungkin bagus untuk dimiliki aplikasi saya. Tetapi apakah mungkin untuk membuat status Loading menjadi fitur opt-in atau opt-out , mirip dengan fallback: false untuk getStaticPaths ? Mungkin export const enableLoadingState = false pada halaman, atau seluruh situs di next.config.js .

https://github.com/zeit/next.js/issues/9524#issuecomment -583962425

Sekali lagi pengingat bahwa Anda menggunakan fitur eksperimental dan kami sedang bereksperimen dengan perilaku saat ini.

Saya menyebarkan situs web SSG (eksperimental) saya ke Sekarang (menggunakan pengaturan default). Ini berfungsi dengan baik, tetapi saya melihat 404 kesalahan di tab jaringan saat menjelajahi situs. Semua 404 kesalahan mengarah ke _next/static/pages/[slug].js .

Apakah ini perilaku yang diharapkan sementara eksperimental? Atau haruskah saya mengubah beberapa pengaturan?

@joostmeijles sepertinya Anda tidak memberikan href dan as ke next/link . Untuk halaman dinamis href harus berupa halaman href='/[slug]' dan as harus berupa URL as='/slug-1'

Saya mendapatkan 3 log di konsol selama build, apakah ini bug?

// Page is showing three logs despite static path only having 2 entries and output generating only two files as intended
export default function Page(props){
    console.log("Page - should only show twice", props); 
    return <><h1>Page</h1></>
}

export async function unstable_getStaticProps(props) {
    console.log("unstable_getStaticProps - should only show twice", props);
    return {
      props
    };

}

export async function unstable_getStaticPaths() {
    console.log("show once")
    return {
        paths: [
        { params: { year: "1901" } },
        { params: { year: "1902" } },
        ]
    }
}

Tidak, itu diharapkan sesuai fallback di RFC.

Tidak, itu diharapkan sesuai fallback di RFC.

export async function unstable_getStaticPaths() {
    console.log("show once")
    return {
        fallback: false,
        paths: [
        // This renders /blog/hello-world to HTML at build time
        { params: { year: "1901" } },
        { params: { year: "1902" } },
        ]
    }
}

Saya mencoba memilih keluar tetapi saya mendapatkan kesalahan ini.

Kesalahan: Kunci ekstra dikembalikan dari stable_getStaticPaths di /[tahun] (fallback) Satu-satunya bidang yang diizinkan saat ini adalah paths

Sekali lagi pengingat bahwa Anda menggunakan fitur eksperimental dan bahwa kami sedang bereksperimen dengan perilaku saat ini dan tidak semuanya diterapkan.

Apakah fitur getStaticProps hanya tersedia untuk halaman?
Akan menarik untuk aplikasi/dokumen juga, misalnya mengambil beberapa konfigurasi global untuk aplikasi?

Saya telah 'berhasil' menerapkan ini dan saya senang dengan hasilnya sejauh ini .. tapi saya bertanya-tanya apakah ada cara untuk membuat build berikutnya 'lebih cepat'? Misalnya, periksa apakah halaman yang dihasilkan SSG tidak berubah dan jangan buat ulang? (Mungkin angan-angan dari saya)

@timneutkens Apakah ada rencana untuk menambahkan generator sitemap.xml untuk halaman SSG? Saya bahkan tidak berbicara tentang rute dinamis karena menurut saya lebih mudah untuk menerapkannya hanya untuk halaman statis untuk saat ini.

@timneutkens Apakah ada rencana untuk menambahkan generator sitemap.xml untuk halaman SSG? Saya bahkan tidak berbicara tentang rute dinamis karena menurut saya lebih mudah untuk menerapkannya hanya untuk halaman statis untuk saat ini.

Ya ini akan menjadi pilihan yang bagus. Saat ini membuat sendiri dengan SSR. (tetapi file sitemap.xml membutuhkan waktu lama untuk dimuat)

https://github.com/zeit/next.js/issues/9524#issuecomment -585293270

Awalnya hanya untuk halaman karena akan ada pekerjaan lain yang memengaruhi getStaticProps setelah mendarat.

https://github.com/zeit/next.js/issues/9524#issuecomment -586957539

Ya tapi bukan sebagai bagian dari RFC ini. Akan ada tindak lanjut setelah ini mendarat.

@timneutkens Saya pikir implementasi untuk halaman SSG mudah karena Anda dapat mendorong URI ke dalam array setiap kali Berikutnya membangun halaman statis dan kemudian, ketika itu berakhir, cukup petakan array ke setiap tag XML, gabungkan dan sisipkan di tengah dari tag <sitemapindex> . getStaticProps dapat memiliki kunci lain di objek pengembalian bernama excludeFromSitemap jadi defaultnya adalah semua halaman disertakan dalam sitemap.xml tetapi dengan opsi untuk tidak ikut.

Jika itu masalahnya, pengembang akan memiliki kontrol yang baik atas halaman statis mana yang akan masuk ke peta situs (misalnya: jika fungsi [foo] getStaticPaths mengembalikan jalur dengan foo params 'abc' dan 'xyz' tetapi hanya file 'abc' harus ada di peta situs, pengembang akan dapat mengatur excludeFromSitemap menjadi true jika parameter ==='xyz' di getStaticProps .

Juga, untuk halaman SSR dan statis, dimungkinkan untuk mengekspor konstanta (yaitu export const excludeFromSitemap = true; ) dari file halaman, seperti getServerProps , getStaticPaths dan getStaticProps diekspor.

Di halaman SSG jika ada konstanta excludeFromSitemap diekspor (default halaman) dan kunci itu juga ada di objek yang dikembalikan dari fungsi getStaticProps (khusus jalur), nilai yang diekspor harus bertindak sebagai default nilai untuk semua jalur di halaman itu dan jalur tertentu excludeFromSitemap , ketika ada di objek getStaticProps , harus mengesampingkan default halaman (sehingga halaman dapat melakukan export cosnt excludeFromSitemap = true dan kemudian tambahkan kunci excludeFromSitemap ke objek yang dikembalikan dari getStaticProps dengan nilai false untuk mengecualikan semua jalur dari peta situs kecuali yang spesifik itu).

Kode untuk menambahkan ke array akan menjadi seperti ini (saya menghitung tabel kebenaran dan mendapatkan ekspresi boolean minimum dengan peta Karnaugh):

//...somewhere else
const validExcludeFromSitemapTypes = ['boolean','undefined'];

//...for each path
const isSSG = !!getStaticPropsReturnedObj && typeof getStaticPropsReturnedObj === "object";
if(
    validExcludeFromSitemapTypes.indexOf(typeof pageExports.excludeFromSitemap)<0 ||
    (isSSG && validExcludeFromSitemapTypes.indexOf(typeof getStaticPropsReturnedObj.excludeFromSitemap)<0)
) {
    throw new Error("'excludeFromSitemap' can either be ommited (undefined) or be a boolean");
}
const defaultExcludedValue = !!pageExports.excludeFromSitemap;
const hasSpecificExcluded = isSSG && typeof getStaticPropsReturnedObj.excludeFromSitemap !== "undefined";
const specificExcludedValue =  isSSG ? !!getStaticPropsReturnedObj.excludeFromSitemap : false;

if(!specificExcludedValue && (!defaultExcludedValue || hasSpecificExcluded))
    sitemapURIs.push(correctlyEncodedURI);

Mengubah array menjadi peta situs akan semudah melakukan ini (dengan asumsi URI dalam array sudah dikodekan dan difilter oleh !excludeFromSitemap ):

function createSitemap(sitemapURIs: string[]): string {
    return `<sitemapindex>${sitemapURIs.map(u=>`<sitemap><loc>u/loc></sitemap>`).join('')}</sitemapindex>`;
}

Saya pikir fitur ini akan cocok di Next.JS karena bagian dari misinya adalah memberikan skor SEO 100 kepada pengguna dan memiliki sitemap.xml akan sangat membantu! ( robots.txt berpotensi juga dihasilkan dengan menambahkan else ke kondisi yang menambahkan jalur ke larik peta situs untuk menambahkan jalur itu ke larik lain dari halaman yang tidak diizinkan)

Dalam versi rilis saat ini, saat menggunakan unstable_getStaticPaths bersama dengan fungsi unstable_getStaticProps , Anda tidak dapat membuat panggilan api ke fungsi yang ada di /api/ .
Karena server tidak berjalan, tidak mungkin untuk membuat permintaan yang sesuai dan menghasilkan props statis dengan cara ini.
Anda juga harus tidak menyediakan fungsi jalur (yang pada dasarnya membuat SSR ini dengan cache, yang masih bagus!) atau mengandalkan SSR daripada SSG.

Mungkin ini akan menjadi tambahan yang bagus untuk fitur ini? Saya tidak yakin apa cara terbaik di sini, saya telah membaca proposal di tempat lain, yang menyarankan pintasan permintaan http, dengan rute SSR dan /api , ini juga berguna di sini.

Tetapi semua ini tentu saja berarti menjalankan kode di lingkungan build, yang akan melakukan panggilan ke layanan/panggilan db lain atau yang serupa. Ini harus dijelaskan ketika ini diterapkan, tetapi ini akan menjadi tambahan yang keren untuk fitur ini.

@reckter Ya, saya sendiri baru saja melakukan hal serupa. Saya harus terhubung ke db saya untuk setiap permintaan halaman terpisah saat mereka dibuat secara statis. Merasa sangat aneh...

Saya harap itu bukan kasus penggunaan terakhir

Akan menyenangkan untuk memiliki semacam skrip inisialisasi yang dapat Anda atur dari next.config atau sesuatu ...

@reckter Cara pintas permintaan HTTP ke rute API dari SSG/SSR akan sangat bagus! Rasanya aneh membuat permintaan jaringan untuk diri saya sendiri di salah satu dari skenario itu.

Bagaimanapun, solusi yang mungkin untuk mengakses rute API selama SSG adalah dengan memiliki server lokal yang hanya menjalankan rute /api sebelum mengkompilasi halaman statis! Jadi langkah-langkah pembuatannya adalah:

  1. Luncurkan server (mungkin disebut "server kompilasi api" atau semacamnya) hanya melayani rute /api
  2. Jalankan unstable_getStaticPaths
  3. Jalankan unstable_getStaticProps
  4. Kompilasi halaman statis

@reckter pada dasarnya Anda tidak perlu memanggil rute API, Anda dapat memanggil fungsi yang diimplementasikannya secara langsung, ini juga menghindari banyak overhead yang disebabkan oleh http.

Pada dasarnya jika saat ini Anda memiliki rute API yang terlihat seperti ini:

import myDb from 'mydatabaseprovider'
const db = myDb()

export default async (req, res) => {
  cont myData = await db.query('posts')
  res.json(myData)
}

Anda akan mengubahnya menjadi:

import myDb from 'mydatabaseprovider'
const db = myDb()

export async function getData() {
  const myData = await db.query('posts')
  return myData
}

export default (req, res) => {
  const myData = await getData()
  res.json(myData)
}

Dan kemudian di halaman Anda:

import {getData} from './api/myfunction'

export async function getStaticProps() {
  const myData = await getData()
  return {
    props: {
     myData
   }
  }
}

Akan sulit untuk melakukan hal yang sama untuk GraphQL API. Dan juga untuk sebagian besar REST.

Panggilan API != mengambil dari DB (secara umum)
Hampir selalu ada beberapa logika bisnis di lapisan API seperti penggantian nama bidang, pemformatan ulang data, dll.

Saya yakin Anda memiliki alasan untuk melarang panggilan pages/api ... tetapi bypass API yang sebenarnya tidak akan mudah atau murah. Dan beberapa milidetik yang dihemat tidak akan melebihi biaya untuk kode tambahan/kompleksitas IMO.

Juga terasa aneh bahwa permintaan ke API apa pun akan diizinkan. Kecuali milikmu sendiri

menggunakan unstable_getStaticPaths menyebabkan halaman dimuat ulang, kehilangan status saat ini di redux misalnya. Apakah perilaku ini akan berubah di masa depan?

edit: tampaknya perilaku ini dapat dielakkan dengan menggunakan opsi as di tautan atau router

<Link
  href='/item/[key]'
  as={`/item/${itemName}`}
>
router.push(
  '/item/[key]',
  `/item/${itemName}`
);

@meesvandongen selalu seperti itu. Jika <Link> tidak valid, Anda akan dibawa ke bagian backend, yang pada dasarnya berfungsi sebagai <a> . Fragmen dinamis seperti [key] harus dipasangkan dengan nilai yang sesuai.

@reaktivo pages/[lang]/blog/[id].js -> di getStaticPaths berikan semua url untuk dirender secara statis.

https://github.com/zeit/next.js/issues/9524#issuecomment -562625858
dalam hal ini perlu menambahkan fungsi getStaticPaths dan getStaticProps untuk setiap halaman kecuali index.js.
Jika ada beberapa halaman mdx, proyek lebih sulit dipertahankan

pertimbangkan untuk mengubah atau kompatibel dengan metode getStaticPaths getStaticProps statis. https://github.com/zeit/next.js/issues/9524#issuecomment -558617056
Jika demikian, halaman dapat dibungkus dengan fungsi tingkat tinggi atau komponen tingkat tinggi HOC).
Dengan cara ini kode lebih mudah dipelihara dan lebih nyaman untuk TypeScript.


gemetar pohon vs dinamis. Pertukaran yang memusingkan.😂

Dengan 9.2.3-canary.13 saya mencoba menggunakan fallback: false di getStaticPaths seperti ini:

  return {
    fallback: false,
    paths: slugs.map(slug => ({params: {slug: slug}}))
  }

tetapi gagal dengan kesalahan berikut:

Error: Extra keys returned from unstable_getStaticPaths in /blog/[slug] (fallback) Expected: { paths: [] }

Dengan 9.2.3-canary.13 saya mencoba menggunakan fallback: false di getStaticPaths seperti ini:

  return {
    fallback: false,
    paths: slugs.map(slug => ({params: {slug: slug}}))
  }

tetapi gagal dengan kesalahan berikut:

Error: Extra keys returned from unstable_getStaticPaths in /blog/[slug] (fallback) Expected: { paths: [] }

Saya pikir Anda memerlukan peta tingkat yang lebih tinggi, jadi peta mengembalikan objek yang Anda miliki saat ini, tetapi dengan siput yang unik. alih-alih pemetaan di jalur.

Saya belum memperbarui versi saya di nextjs, tetapi seharusnya serupa:

return data.map(item => {
    return {
      params: {
        slug: item.slug,
      },
    }
  })

@jorngeorg ini adalah PR terbuka: https://github.com/zeit/next.js/pull/10701

Kontribusi yang fantastis! Ini benar-benar meningkatkan proses rendering statis.

Saya sarankan menambahkan ke dokumen bahwa pada rute dinamis, "fallback" akan dihasilkan tanpa panggilan apa pun ke getStaticProps - artinya Anda harus mengkodekan komponen Anda untuk memperhitungkan kasus di mana alat peraga kosong.

Atau Anda dapat mengubah perilaku untuk memanggil getStaticProps tanpa konteks saat membuat fallback. Ini akan konsisten dengan cara kerja next export saat ini (misalnya /p/[id].js diekspor ke /p/[id].html dengan menjalankan getInitialProps tanpa konteks).

  • getStaticProps - Ikut serta dalam pembuatan statis (SSG) pada waktu next build .
  • getServerProps - Ikut serta dalam rendering sisi server (SSR) yang merender sesuai permintaan.

10722

Ganti nama getServerProps menjadi getServerSideProps.

Saya sarankan menambahkan ke dokumen bahwa pada rute dinamis, "fallback" akan dihasilkan tanpa panggilan apa pun ke getStaticProps - artinya Anda harus mengkodekan komponen Anda untuk memperhitungkan kasus di mana alat peraga kosong.

Poin bagus untuk menyebutkannya! Saya juga memiliki beberapa kesalahan build/deployment karena saya melewatkannya.

Memperbarui RFC untuk mencerminkan perubahan

@timneutkens

  • Permintaan selanjutnya ke jalur yang sama akan melayani halaman yang dihasilkan

Saya berasumsi ini berarti Next.js akan men-cache halaman yang dihasilkan? Apakah ini cache dalam memori? Apakah cache ini dibatasi oleh batasan atau dapatkah ini mengakibatkan kebocoran memori?

Saat Anda menggunakan next start ia menggunakan lru-cache mirip dengan contoh caching saat ini, saat ini batas default adalah 50MB, kami mungkin membuatnya dapat dikonfigurasi nanti: https://github.com/zeit/next.js/ gumpalan/canary/paket/berikutnya/berikutnya-server/server/spr-cache.ts#L90

Saat Anda menghosting di ZEIT Now, pembuatan dan caching terjadi pada CDN/Proxy sehingga cara kerjanya sedikit berbeda dan Anda tidak perlu khawatir tentang kebocoran memori atau jika Anda melampaui batas lru.

👍 ok, sepertinya masuk akal. Kurang lebih itulah yang ada dalam pikiran saya sebagai perilaku default yang masuk akal.

  • getStaticProps - Ikut serta dalam pembuatan statis (SSG) pada waktu next build .
  • getServerProps - Ikut serta dalam rendering sisi server (SSR) yang merender sesuai permintaan.

10722

Ganti nama getServerProps menjadi getServerSideProps.

Mengapa mengganti nama? IMHO getServerProps cukup akurat dan lebih pendek untuk mengetik, menambahkan Side terasa berlebihan bagi saya.

Saya bertanya-tanya apakah ada perubahan yang dilakukan pada metode getStaticPaths? Halaman dinamis saya tidak lagi dibuat sebagai halaman statis, mereka diekspor sebagai fungsi lambda sekarang?

Apakah saya benar ketika perilaku default sekarang adalah halaman pertama kali dirender sebagai lambda dan hanya setelah mengunjungi halaman tertentu halaman dibuat menjadi halaman statis? (seperti yang disebutkan di fallback)

@erhankaradeniz Tidak ada perubahan yang dilakukan pada getStaticPaths yang akan mengakibatkan halaman Anda menjadi Lambdas. Ini kemungkinan kesalahan dalam penggunaan.

Bisakah Anda menunjukkan kode Anda sehingga kami dapat mengidentifikasi masalahnya?

@Timer untuk saat ini saya telah kembali ke [email protected] di mana saya masih dapat menggunakan params, sampai saya mengetahui mengapa itu tidak berfungsi dengan jalur.

ini adalah bagaimana saya saat ini membuat jalur saya:

return cityData.map(city => {
    return {
      params: {
        country: city.countrySlug,
        city: city.slug,
      },
    }
  })

dan di halaman lain saya lakukan:

return cityData.map(city => {
    return {
      params: {
        country: city.countrySlug,
        city: city.slug,
      },
    }
  })

belum berhasil mengonversinya ke rilis kenari baru dengan jalurnya. Saya pasti melakukan sesuatu yang salah, karena console.logs bahkan tidak terpicu dalam getStaticPath

Saya memiliki masalah dengan pra-rendering jalur bersarang dan SSG:

// pages/[lang]/[...slugs].js

export async function getStaticPaths() {
  let knex = await import("knex/client").then(m => m.default)
  let pages = await knex("page").select(["lang", "url"])
  return {
    fallback: true,
    paths: pages.map(page => {
      return {
        params: {
          lang: page.lang,
          slugs: page.url == "/" ? [] : page.url.slice(1).split("/"),
        }
      }
    }),
  }
}

mengarah ke

Error occurred prerendering page "/en/". Read more: https://err.sh/next.js/prerender-error:
Error: The provided export path '/en/' doesn't match the '/[lang]/[...slugs]' page.

untuk halaman Beranda. Untuk beberapa alasan NextJS gagal mencocokkan

{lang: "en", slugs: []}

ke

/[lang]/[...slugs]

Jika saya memberikan {lang: "en", slugs: ["/"]} itu dibuat tetapi dengan URL yang salah:

├ ● /[lang]/[...slugs]      875 B        204 kB
├   ├ /en/credits
├   ├ /en/%2F

Sebagai catatan, getServerSideProps berfungsi dengan baik dengan pengaturan serupa.

Saya tahu ini eksperimental tetapi utas ini untuk memberikan umpan balik, bukan?

pages/[lang]/[...slugs].js cocok dengan /en/abcdef dan bukan /en , untuk itu saat ini Anda harus membuat pages/[lang]/index.js .

Ada permintaan fitur yang terbuka untuk ini: https://github.com/zeit/next.js/issues/10488

Pertama-tama, ini luar biasa. Saya sudah berharap untuk memiliki sesuatu seperti ini di Next.js sehingga saya akhirnya bisa pindah dari Gatsby.js dan memiliki aplikasi hybrid (statis + dinamis).

Saya mencoba versi aplikasi kompleks kenari dan setengah matang bekerja dengan baik. Saya akui saya belum membaca semua komentar di sini tetapi tidak yakin apakah pengguncangan pohon sudah diterapkan.

getStaticPaths terasa lebih seperti setStaticPaths mana kita mendefinisikan jalur statis untuk perilaku SSG. Hal semacam itu membuatku sedikit bingung.

Saya ingin tahu apakah kami dapat meningkatkan waktu pembuatan dengan memiliki kategori pembuatan? Saya tahu ini akan memperumit pengaturan tetapi itu akan sangat berharga. Mari saya jelaskan:

Bagaimana jika kita memiliki sesuatu seperti setBuildCategory yang menyetelnya ke blog atau pages atau apa pun yang diinginkan seseorang 2020-content . Kemudian SSG builder mencari kategori halaman yang diubah dan hanya mencoba membangun kembali kategori tersebut dari kombinasi cache + render baru. Sesuatu seperti ini dapat membantu kami mempercepat SSG dan menghindari waktu pembuatan yang besar untuk hal-hal yang tidak mudah berubah banyak tetapi masih dapat berubah sehingga tidak dapat diarsipkan.

Jika itu masuk akal; senang untuk menelepon dan mengobrol tentang ini.

Bagaimana cara menangani getServerSideProps dengan implementasi server khusus?

if (pathname === '/a') {
  app.render(req, res, '/b', query)
}

Pada contoh di atas, mengunjungi /a akan merender halaman pages/b.js . Tetapi pengalihan sisi klien ke /a mencoba mengunduh file a.json , yang tidak ada dalam kasus ini.

Apakah kita seharusnya memiliki kondisi yang sama untuk permintaan ke /_next/data/{BUILD_ID}/{PAGE}.json untuk merender file JSON yang berbeda?

Untuk menggunakan fallback: true di getStaticPaths, bagaimana cara mendapatkan objek req? Tampaknya saat ini saya tidak bisa. Alasan saya membutuhkannya adalah untuk mengambil beberapa cookie dari browser untuk mengautentikasi rute

@tylermcrobert bagaimana Anda membayangkan mengambil cookie ketika tidak ada permintaan sama sekali?!
Rute dengan backend yang bergantung pada permintaan pengunjung sebenarnya tidak dapat dibuat statis dengan definisi "statis" dan "dinamis". Bukan untuk mengatakan Anda tidak dapat menggabungkan statis dan auth... hanya saja bagian auth akan menjadi milik API dan kode klien, bukan halaman.

Bagaimana cara menangani getServerSideProps dengan implementasi server khusus?

if (pathname === '/a') {
  app.render(req, res, '/b', query)
}

Pada contoh di atas, mengunjungi /a akan merender halaman pages/b.js . Tetapi pengalihan sisi klien ke /a mencoba mengunduh file a.json , yang tidak ada dalam kasus ini.

Apakah kita seharusnya memiliki kondisi yang sama untuk permintaan ke /_next/data/{BUILD_ID}/{PAGE}.json untuk merender file JSON yang berbeda?

Next.js mendukung parameter rute dinamis, jadi pemetaan ulang di server khusus jarang diperlukan lagi: https://nextjs.org/docs/routing/dynamic-routes

Pendekatan yang Anda uraikan sudah tidak berfungsi dengan <Link> (akan menyebabkan transisi satu halaman penuh) jadi getServerSideProps sudah berfungsi.

@tylermcrobert bagaimana Anda membayangkan mengambil cookie ketika tidak ada permintaan sama sekali?!
Rute dengan backend yang bergantung pada permintaan pengunjung sebenarnya tidak dapat dibuat statis dengan definisi "statis" dan "dinamis". Bukan untuk mengatakan Anda tidak dapat menggabungkan statis dan auth... hanya saja bagian auth akan menjadi milik API dan kode klien, bukan halaman.

Mungkin saya salah memahami opsi mundur dalam kasus itu. Apa yang Anda katakan benar-benar masuk akal dalam konteks waktu pembuatan.

Bukankah fallback: true untuk saat tidak ada rute yang telah ditentukan? Dalam hal ini, mundur akan dicapai dari browser, bukan?

@tylermcrobert yes fallback: true case memiliki permintaan tetapi API harus disatukan oleh "penyebut umum terendah". Saya tidak dapat membayangkan sistem kerja di mana semuanya dibangun dengan satu set tempat dan kemudian secara bertahap diperbarui dengan set tempat yang sama sekali berbeda. Ini akan menjadi bencana untuk mendukung.

Saya pikir Anda melewatkan poin bahwa build inkremental itu masih akan di-cache di antara build. Jadi peran pengunjung pertama akan mempengaruhi hasil build untuk semua pengguna berikutnya! Kedengarannya seperti ide yang buruk.

@ivan-kleshnin Saya mengerti & tentu saja setuju. Alasan saya bertanya adalah karena kasus penggunaan khusus saya.

Saya menggunakan CMS tanpa kepala yang memungkinkan fungsionalitas pratinjau sehingga halaman yang perlu dipratinjau tidak akan disertakan pada waktu pembuatan (Karena entri yang dipratinjau tidak akan ada pada saat ini). Saya pikir ini adalah kasus di mana opsi mundur akan masuk.

Untuk mengakses pratinjau itu, saya memerlukan akses ke referensi pratinjau api yang diberikan melalui cookie.

Apakah ini kasus di mana saya harus menghapus useStaticProps seluruhnya? Saya tidak ingin kehilangan manfaat dari build statis karena saya tidak dapat melihat pratinjau dokumen saya.

Daya tarik RFC ini dibandingkan sesuatu seperti gatsby adalah memberi kita "kontrol hybrid" dengan pembuatan situs statis yang membuatnya tidak terlalu merepotkan untuk bekerja dengan CMS tanpa kepala

Saya menggunakan CMS tanpa kepala yang memungkinkan fungsionalitas pratinjau sehingga halaman yang perlu dipratinjau tidak akan disertakan pada waktu pembuatan (Karena entri yang dipratinjau tidak akan ada pada saat ini). Saya pikir ini adalah kasus di mana opsi mundur akan masuk.

Nantikan, segera

Jadi jika saya memahami ini dengan benar, kami dapat menggunakan fallback true ketika misalnya dalam kasus saya seorang pengguna mendaftar (tidak ada halaman statis yang dihasilkan karena ini adalah halaman/pengguna baru) tetapi ketika profil mendapat kunjungan, itu dibuat secara otomatis?

Erhan Karadeniz
http://www.erhankaradeniz.com

Pada 4 Maret 2020, pukul 20:25, Tim Neutkens [email protected] menulis:


Saya menggunakan CMS tanpa kepala yang memungkinkan fungsionalitas pratinjau sehingga halaman yang perlu dipratinjau tidak akan disertakan pada waktu pembuatan (Karena entri yang dipratinjau tidak akan ada pada saat ini). Saya pikir ini adalah kasus di mana opsi mundur akan masuk.

Nantikan, segera


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub, atau berhenti berlangganan.

Data pengguna adalah contoh buruk karena Anda ingin mengambil sisi klien itu. Penggantian tersedia untuk menghasilkan halaman statis sesuai permintaan yang belum dibuat pada waktu pembuatan. Misalnya Anda mungkin ingin menghasilkan 100 posting blog teratas pada waktu pembuatan dan tidak menghasilkan yang lain dengan lalu lintas yang lebih sedikit.

Documents akan segera mendapatkannya.

Ya, yang saya maksud adalah halaman placeholder.. Saya memang mengambil data pengguna di sisi klien.

@timneutkens Apakah ada cara untuk menghapus atau membangun kembali halaman tertentu yang dibuat secara statis?

Hai!!! Terdengar seperti aplikasi yang optimal. Saya sangat menyukai React dan Next!!! Membuat semuanya begitu elegan dan sederhana untuk kita gunakan!! Tapi contohnya termasuk pengertian blog. Saya ingin melihat contoh implementasi saat menanyakan CMS Tanpa Kepala dan membuat pengambilan dilakukan per halaman/posting sebagai ekspor sebagai item statis.

// bersorak, karena sudah dekat hari jumat !!!

@timneutkens ini seru

Satu skenario yang sering kami lakukan dan saya belum memiliki solusi sempurna dengan next.js atau gatsby kecuali rute dinamis atau menghasilkan proyek dalam satu lingkaran:

Untuk alasan historis, kami harus berurusan dengan beberapa domain (dan tidak ada keinginan untuk mengubahnya) yang menyajikan halaman yang sama/tepat dengan pengecualian untuk harga, mata uang, nomor telepon dukungan, dan pemilih bahasa. Secara alami, sebagian besar halaman pemasaran itu cukup statis dan akan cukup untuk membuatnya setiap hari atau setiap minggu (vs membuatnya dirender pada setiap permintaan).

Pertanyaan/pemikiran saya: apakah Anda melihat cara (di masa depan?) getStaticPaths dapat menghasilkan halaman berdasarkan sesuatu yang bukan parameter rute tetapi dapat digunakan pada tingkat permintaan untuk beralih di antara mereka (mis. fungsi mengembalikan hasil statis yang dibuat sebelumnya berdasarkan locale )

Konkret ini berarti https://mysite.com/my-product dan https://mysite.co.uk/my-product akan melayani dua halaman statis yang berbeda tetapi tanpa kita harus membuat aplikasi berikutnya 50x kali atau harus menekan CMS pada setiap permintaan😅

Terima kasih sebelumnya dan ingin mendengar pendapat Anda, terutama jika itu adalah sesuatu untuk masa depan yang dapat diselesaikan/dikerjakan ❤️

Saya sedang memikirkan kasus penggunaan di mana saya ingin menggunakan SSG untuk halaman arahan dengan lalu lintas tinggi untuk SEO dan untuk mengurangi beban server, tetapi masih ingin data saat ini digunakan setelah hidrasi, dan pada perutean sisi klien ke halaman ini. Apakah itu mungkin?

Jadi pada dasarnya pada perutean sisi klien ke halaman ini, perilakunya harus seperti getInitialProps (data saat ini diambil sebelum halaman terlihat). Dan pada perutean sisi server ke halaman ini, html statis harus disajikan dan dihidrasi, dan kemudian (opsional) beberapa respons api diambil untuk memperbarui beberapa data di halaman.

Saya baru saja bermain dengan unstable_getStaticProps hanya untuk mencobanya dan saya mengalami konflik yang menyenangkan: sulit untuk menggunakan rute API dengan getStaticProps .

Jangan memperhatikan semantik kode, tetapi hanya aliran pengambilan data:

// pages/api/healthcheck.ts
import { NextApiResponse, NextApiRequest } from 'next';

export type ApiHealthCheckResponse = {
  message: 'ok';
};

const healthCheckHandler = (
  req: NextApiRequest,
  res: NextApiResponse<ApiHealthCheckResponse | ''>,
) => {
  if (req.method === 'GET') {
    return res.status(200).json({ message: 'ok' });
  }

  return res.status(405).send('');
};

export default healthCheckHandler;
// pages/index.js
// ...

export async function unstable_getStaticProps() {
  return {
    props: {
      healthcheck: (await fetch('localhost:3000/api/healthcheck').json())
    },
  };
}

Pembuatan halaman akan macet pada waktu pembuatan karena server tidak berjalan. Saya tidak yakin apakah ini usecase yang valid, karena getStaticProps tidak boleh digunakan dengan sesuatu yang terlalu dinamis, tetapi saya pikir itu adalah kasus yang menarik untuk dibagikan (saya benar-benar dapat membayangkan titik akhir Route API yang bertanggung jawab untuk mendapatkan data dari API lain dan memformat ulang.

@martpie Anda mungkin ingin melihat komentar ini: https://github.com/zeit/next.js/issues/9524#issuecomment -589772756

Dukungan Generasi Situs Statis (SSG) generasi berikutnya telah dirilis sebagai stabil di Next.js 9.3!

Rilis ini juga mencakup dukungan untuk "Mode Pratinjau", atau kemampuan untuk mengabaikan halaman yang telah diprarender secara statis dan merender halaman sesuai permintaan untuk pengguna yang berwenang .

Anda dapat membaca lebih lanjut tentang itu di posting blog kami. Jika Anda lebih paham, langsung buka dokumen kami!

Silakan kirim pertanyaan apa pun ke Komunitas GitHub Next.js !

Ini sangat keren! Terima kasih atas kerja kerasnya!

Fitur baru ini sepertinya tidak berfungsi dengan saga dan redux sekarang

Apakah halaman ini membantu?
0 / 5 - 0 peringkat