eidellev / inertiajs-adonisjs

279 stars 17 forks source link

SSR Support #51

Closed arthur-er closed 2 years ago

arthur-er commented 2 years ago

SSR Support for Inertia is officially out, and should be here as well

Currrently Inertia docs suggests running a separate server for rendering the pages as the official adapters don't run in NodeJS, but as Adonis is a NodeJS framework we can add support for Inertia SSR on the same server.

I'm currently using SSR without support from the adapter (using a view global that renders and returns the inertia page) and its working as a breeze.

My suggestion to implement this is just including a SSR Render config function on the already existing inertia config that receives the render function to support different front-end frameworks and include the SSR request in the existing @inertia edge tag with a extra @inertiaHead tag to match Inertia Laravel implementation

I'm willing to work in this if approved

eidellev commented 2 years ago

Thank you. I completely agree and was planing on starting to implement SSR later this week. If you have a working implementation and would like to open a PR that would be great. Please note that I just added a contribution guide to the readme. Let me know if you have any questions. This is really exciting :-)

arthur-er commented 2 years ago

I don't know exactly how to fit it into the package, current it works like that:

// start/view.ts
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import View from '@ioc:Adonis/Core/View'

View.global('ssr', (page) => {
  try {
    return createInertiaApp({
      resolve: (name: string) => require(`Resources/Pages/${name}`).default,
      page,
      render: ReactDOMServer.renderToString,
      setup: ({ App, props }) => React.createElement(App, processProps(props)),
    })
  } catch (error) {
    return undefined
  }
})
@set('ssr_page', await ssr(page))
<!DOCTYPE html>
<html>
  <head>
    @each(element in ssr_page?.head)
      {{{ element }}}
    @end
  </head>
  <body>
    @if(ssr_page)
      {{{ ssr_page.body }}}
    @else
      @inertia()
    @end
  </body>
</html>
kevin-DL commented 2 years ago

I don't know exactly how to fit it into the package, current it works like that:

// start/view.ts
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import View from '@ioc:Adonis/Core/View'

View.global('ssr', (page) => {
  try {
    return createInertiaApp({
      resolve: (name: string) => require(`Resources/Pages/${name}`).default,
      page,
      render: ReactDOMServer.renderToString,
      setup: ({ App, props }) => React.createElement(App, processProps(props)),
    })
  } catch (error) {
    return undefined
  }
})
@set('ssr_page', await ssr(page))
<!DOCTYPE html>
<html>
  <head>
    @each(element in ssr_page?.head)
      {{{ element }}}
    @end
  </head>
  <body>
    @if(ssr_page)
      {{{ ssr_page.body }}}
    @else
      @inertia()
    @end
  </body>
</html>

Hello, this looks great, would it work the same way for Vue?

arthur-er commented 2 years ago

Yes, just swap the react part of inertia setup for the vue ones

kevin-DL commented 2 years ago

Thank you I will try that.

On Wed, 23 Feb 2022, 11:49 Arthur Emanuel, @.***> wrote:

Yes, just swap the react part of inertia setup for the vue ones

— Reply to this email directly, view it on GitHub https://github.com/eidellev/inertiajs-adonisjs/issues/51#issuecomment-1048701630, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB6YYW5PEAKYZHH4DWJUHRDU4TCTZANCNFSM5LSLLDOQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

kevin-DL commented 2 years ago

So i tried like this

View.global('ssr', async (page) => {
  try {
    return createInertiaApp({
      resolve: (name) => require(`Resources/js/Pages/${name}.vue`),
      page,
      render: renderToString,
      setup: ({ app, props, plugin }) => {
        return createSSRApp({
          render: () => h(app, props),
        }).use(plugin)
      },
    }).catch((e) => {
      console.log({
        e,
      })
    })
  } catch (error) {
    console.log({
      error,
    })
    return undefined
  }
})

but i keep getting an error

`