chrisvfritz / prerender-spa-plugin

Prerenders static HTML in a single-page application.
MIT License
7.32k stars 634 forks source link

prerendering the route "/" adds the pre-rendered html for that route to all routes #218

Open vesper8 opened 6 years ago

vesper8 commented 6 years ago

I'd like to pre-render my "/" route which is my public (for logged out users) landing page.

All my protected apps are something other than "/", including the default route for when you are logged in.

However I've noticed that if I include the "/" route in the routes to pre-render, it replaces the main index.html which is used as an entry point for the app and as such that html is included everywhere.

This is causing problems, problems that I can probably work around but I don't think it should be working this way? Why should the /user/profile (example) include the entire html that makes up the "/" landing page?

How can I avoid this if I really want to use "/" for my landing page ?

JoshTheDerf commented 6 years ago

@vesper8 The solution for this would actually be to prerender all of your other routes as well, which will render (in theory) with the log-in screen.

vesper8 commented 6 years ago

all of my authorized routes are auth protected meaning that if you visit them while not auth you just get redirected to the auth route which in my case is "/"

Those other routes, the auth routes, can only be visited when you are routed there after fully loading the app, in addition, all those other routes all contain user-specific dynamic content.. don't think those are made for prerendering

I wonder if there would be a way to just remove (with jquery) all of the root page's pre-rendered content if you are on any other page than the root

vesper8 commented 6 years ago

I was able to alleviate part of the problem using an injected variable.. where things were being initialized from my main.js in the logged-out "/" route and then being duplicated again once the app loaded

But I'm still having the problem of the homepage's content flashing for a second on every other page when you do a hard reload

so perhaps pre-rendering all pages is the key.. but as I said above those pages contain user content.

Furthermore some of these routes have route parameters in it.. for example /user/23 so I don't even know how I would deal with prerendering that

For simple routes that don't contain parameters I'm thinking I could either mock the auth-state while the app is prerendering.. so that at least the correct menu nav loads

but really.. once the user is visiting these routes and on the rare case where they do a hard reload.. they have already cached the full app so I would be very happy with just having a "blank index.html".. meaning the ones that are generated by the normal npm run build process be the pregenerated html

This will result in a white page but for a fraction of a second which is fine and much less noticable then seeing the homepage content flash in and out

Any idea how I might achieve this? I think this is a problem many are sure to face with SPAs and should be addressed

JoshTheDerf commented 6 years ago

Honestly if I were you it sounds like you really don't need to prerender. It offers very little value if you're only rendering one route out of many.

If you're using Vue.js, the homepage content flashing issue can (usually) be dealt with by adding the attribute data-server-rendered="true" to your app mount element.

kdeeksha-zz commented 5 years ago

@vesper8 Could you solve the issue? I also have same issue where prerendered '/' content appears first when refresh in other routes like '/signin

vesper8 commented 5 years ago

@kdeeksha my solution was to also pre-render the affected routes.. basically all my routes that are public-facing and important for SEO are all pre-rendered now

however this still happens on routes that are not pre-rendered, if you do a hard refresh on those

did you try the ```data-server-rendered="true"

kdeeksha-zz commented 5 years ago

Yes I Did. But it isn't working. Also, i get webpackJsonp error and prerendered '/' content appears before the actual content specific to route. Did find a way out for this.

On Wed, Oct 24, 2018 at 4:10 PM C-Bass notifications@github.com wrote:

@kdeeksha https://github.com/kdeeksha my solution was to also pre-render the affected routes.. basically all my routes that are public-facing and important for SEO are all pre-rendered now

however this still happens on routes that are not pre-rendered, if you do a hard refresh on those

did you try the ```data-server-rendered="true"

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/chrisvfritz/prerender-spa-plugin/issues/218#issuecomment-432606095, or mute the thread https://github.com/notifications/unsubscribe-auth/AZkwD-6HYoQFJ7K-gMwiDvkI2kN83y5Rks5uoEO4gaJpZM4VHA13 .

henrikmerlander commented 5 years ago

You can use postProcess to rename the prerendered index.html file, so it does not conflict with the existing index.html. Example:

postProcess(renderedRoute) {
  if (renderedRoute.originalRoute === '/')
    renderedRoute.outputPath = path.join(__dirname, 'index.prerendered.html')

  return renderedRoute
},

Then you also need to configure your server to use the prerendered index.html file for the root route while keeping the normal index.html for every other route. Example in express using connect-history-api-fallback:

app.use(
  require('connect-history-api-fallback')({
    rewrites: [
      { from: /^\/$/, to: '/index.prerendered.html' },
    ],
  })
)