frandiox / vitesse-ssr-template

🏕 Opinionated Vue + Vite Starter Template with SSR in Node.js
https://vitesse-ssr.vercel.app/
MIT License
188 stars 29 forks source link

Populate individual pages with data from http requests #12

Closed techieoriname closed 2 years ago

techieoriname commented 2 years ago

Kudos @frandiox great work you have done here.

I saw you populate a page with data before navigation. Great, but can this be done perpage?

usecase fetch a blog post, and use the post title from the response body as the page title using @vueuse/head.

// As an example, make a getPageProps request before each route navigation
    router.beforeEach(async (to, from, next) => {
      if (!!to.meta.state && (!import.meta.env.DEV || import.meta.env.SSR)) {
        // This route has state already (from server) so it can be reused.
        return next()
      }

      // `isClient` here is a handy way to determine if it's SSR or not.
      // However, it is a runtime variable so it won't be tree-shaked.
      // Use Vite's `import.meta.env.SSR` instead for tree-shaking.
      const baseUrl = isClient ? '' : url.origin

      // Explanation:
      // The first rendering happens in the server. Therefore, when this code runs,
      // the server makes a request to itself (running the code below) in order to
      // get the current page props and use that response to render the HTML.
      // The browser shows this HTML and rehydrates the application, turning it into
      // a normal SPA. After that, subsequent route navigation runs this code below
      // from the browser and get the new page props, which is this time rendered
      // directly in the browser, as opposed to the first page rendering.

      try {
        // Get our page props from our custom API:
        const res = await fetch(
          `${baseUrl}/api/get-page-props?path=${encodeURIComponent(
            to.path
          )}&name=${to.name}&client=${isClient}`,
          {
            method: 'GET',
            headers: {
              'Content-Type': 'application/json',
            },
          }
        )

        // During SSR, this is the same as modifying initialState
        to.meta.state = await res.json()
      } catch (error) {
        console.error(error)
        // redirect to error route conditionally
      }

      next()
    })
frandiox commented 2 years ago

The idea is that you return different stuff depending on to.path or to.name in this example. Vitedge is another project that gives you API routes out of the box but I guess you've already found out about that project 😅

techieoriname commented 2 years ago

Yeah thanks alot @frandiox vitedge actually solves my problem here 👍👍👍