Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use hosting with prerender.io #33

Closed
abusedmedia opened this issue Oct 10, 2014 · 93 comments · May be fixed by Jeremip11/firebase-tools#5
Closed

Use hosting with prerender.io #33

abusedmedia opened this issue Oct 10, 2014 · 93 comments · May be fixed by Jeremip11/firebase-tools#5

Comments

@abusedmedia
Copy link

Hi

I'm wondering whether there's a way to use Firebase hosting in conjunction with a service like prerender.io?
This way it would be possible to deploy a webapp (i.e. angularjs app) with SEO capabilities.

Thanks

@cbraynor
Copy link
Contributor

Hi,

Currently Firebase Hosting's rewrite/redirect rules aren't detailed enough for prerendering services, but some of our customers have had success building a pre-render step into their build process for fairly static sites using html5 pushState. They pre-render every page based on the single page app so that the correct content is served up to a crawler, then if the user navigates to another page the webapp takes over and rerenders without a page refresh

This is obviously pretty complicated and obviously not ideal, but we're working on making this much less of a pain point

Hope that helps

Chris

@codingwithoutcomments
Copy link

I realize it's only been two months, but is there an update on this? Since you guys are owned by google now, I'd assume they want sites hosted with firebase to be indexed by their search service.

@cbraynor
Copy link
Contributor

We have no specific update on this at this time, just that SEO is obviously important to us and keeping Firebase Hosting relevant to developers. I hope to have an update for you soon

@alejomendoza
Copy link

Hi guys! I just wanted to know what is the status on this update? is it coming anytime soon? I use Firebase hosting and it is great the only thing I'm concerned is SEO, my site doesn't appear anywhere in google, also I searched for seo integrations with firebase and I couldn't find any solution. I really like to keep everything in one place, so it would be a shame to change to a different service that can serve my pages to google's crawler engine. This would be a huge improvement since I know Firebase is owned by google now. Thank you!

@codingwithoutcomments
Copy link

Also still interested in this service. Thanks!

@playtogga
Copy link

Adding my voice to the thread - would be great to have this feature!

@pandaiolo
Copy link

+1

@tomkanjam
Copy link

I'm waiting for this as well.

As an alternative I'm looking into using https://divshot.com + firebase.

@78lab
Copy link

78lab commented Sep 25, 2015

+1

@DamodarSojka
Copy link

Due to recent announcement of DIvshot and Firebase merge this problem arises again. I have actually moved to Divshot to make use of both free custom Domain and prerender.io capabilities. How is fireabse going to deal with those issues? Are you going to add custom domains to free tier? What about prerender.io?

@mbleigh
Copy link
Contributor

mbleigh commented Oct 13, 2015

We are investigating ways that we might be able to bring JS prerendering to Firebase Hosting, but don't have any firm plans to share at this time. (Personal note: I really want to see it happen).

Because Firebase is opinionated that all sites should be HTTPS-only, we manage SSL certificate provisioning on behalf of our users. The cost involved in doing so prevents us from being able to offer free custom domain hosting.

@DamodarSojka
Copy link

Thanks for a blazing fast (pun intended) answer.

Some sort of SEO capability is more than needed for static web app hosting platforms, so I just hope you guys manage to get that working until middle of December, otherwise lot of devs will need to switch to old-school hosting providers (unfortunately including me).

Second answer makes perfect sense and I consider just jumping on paid tier, its a shame it is not providing same additional scaling thou.

@mbleigh
Copy link
Contributor

mbleigh commented Oct 13, 2015

100% of Firebase Hosting sites are on Fastly's blazing fast (pun regurgitated) CDN. You get all the perks of Divshot's high-performance plan even on the free plan (just not on a custom domain). As for bandwidth, 10GB ends up being a lot of band for a static website.

@DamodarSojka
Copy link

I need to admit that I have not though about Divshot's high-performance perks. Anyway it is a shame I might need to migrate my app and prepare a backend (and delay new features!), while CS degree eats almost all of my time. While my project isn't that advanced others might suffer enormous delays, so again I really hope Firebase will help us become SEO friendly or maybe Divshot will delay its close. I understand this is probably not an option, but if some of us will migrate they might never come back.

@ricolo
Copy link

ricolo commented Oct 14, 2015

Congratulations @mbleigh for the acquisition!

@DamodarSojka, I agree with you completely. I'm an existing Divshot paid user. Prerendering is a must for the marketing/sharing of my website on Facebook. If Firebase does not offer this capability soon, I will have to migrate to other web hosting services.

@akisvolanis
Copy link

+1 for SEO capability

@amika
Copy link

amika commented Oct 14, 2015

We are also paying Divshot customer and Prerender support is necessary for us. Prerender support on Divshot isn't ideal (because of production.blabla.divshot.io URL after sharing) but if there isn't Prerender support on Firebase at all we can't use it. Thanks.

@gareys
Copy link

gareys commented Oct 14, 2015

Likewise, SEO is of utmost importance, whether you're using prerender.io or another comparable solution. This needs to be addressed on Firebase before divshot shuts down.

@julienreszka
Copy link

Yup still having trouble with seo

@pessato
Copy link

pessato commented Oct 20, 2015

+1 - Payed Divshot customer, would require Prerender support to migrate to Firebase.

@grinale
Copy link

grinale commented Oct 23, 2015

Completley agree. Firebase is not a Divshot replacement if it doesn't have prerender capabilities. I am a Divshot paid user. With two months notice of Divshot shutting down. Should I work on migrating to another service ? Do I have to spend my time on configuring a server ? Or keep focused on what I was doing ? Isn't this the idea of the service ? Not having to deal with server issues ? Please explain whether Firebase will be an option for December 14 or should I take my time configuring a server.

@katowulf
Copy link

Gents, Mike has already stated, in its entirety, the status of this feature: We are investigating ways that we might be able to bring JS prerendering to Firebase Hosting, but don't have any firm plans to share at this time. (Personal note: I really want to see it happen).

There is no timeline. We want it as much as you do.

You'll have to decide on your own what you should do. We don't have a public road map. We can't make any guarantees on any timeline, regardless of the number of demands or queries. Sorry it's not happy fluffy answers, but hopefully realistic ones are more useful for your planning.

☼, Kato

@julienreszka
Copy link

Nice to see that you really care about it :) Thank you guys !

@douglascorrea
Copy link

@mbleigh / @katowulf One question about that plan to bring JS prerendering to Firebase: How it JS prerendering will be better the current SEO support Firebase is offering?

Based on this SO answer, Firebase is already providing SEO out-of-the-box since ng-conf 2015.

So I don't get the pros of still trying to use Prerender.io on Firebase.

@mbleigh
Copy link
Contributor

mbleigh commented Nov 11, 2015

@douglascorrea for Google SEO the improvements will be marginal, but (as it turns out) Google isn't the only crawler out there 😄

The biggest gain for this is for sites that want to offer better support for Facebook OpenGraph tags, Twitter cards, and non-Google search engines.

@douglascorrea
Copy link

Thank you @mbleigh, it clarify things and makes me think that we really want that support, or some kind of alternative like @drtriumph said in his comment.

@douglascorrea
Copy link

I was looking for a solution, and I found the following details that could be good for other readers:

  • On October, 2015 Google deprecated the recommendation of using escaped_fragment and the hashbang (!#). So, for Google, every SPA should use html5 pushstate (html5mode on angularjs). But they will continue supporting hashbang (!#) and translating it to escaped fragment for while.
  • Facebook and probably others crawlers still need the escaped_fragment, the Facebook automatic translate hashbang to _escaped_fragment notation. And probably other crawlers do the same since it was the previous recommendation from google.
  • Since Firebase do not support redirects based on User-Agent yet, our hope remains on crawlers translating hasbangs (!#) to escape_fragament like this:
    If your URLs look like this:
    http://www.example.com/#!/user/1
    Then access your URLs like this:
    http://www.example.com/?_escaped_fragment_=/user/1

So, for while, one idea to figure this out could be this:

  • Do not use html5 pushstate (html5 mode on Angular) and use hashbang instead (!#)
  • Use prerender.io to create static/cached version of every page you want in you application (like normal prerender process).
  • Develop an plugin that store that cached version in a folder structure that starts with the folder ?_escaped_fragment_= and create folders like:
    If your URLs look like this:
    http://www.example.com/#!/user/1
    The generated folder will be
    ?_escaped_fragment_= +- /user +- /1

Where the 1 file will be the actual html file.

  • Deploy that folder in your root firebase folder using firebase-tools (this process could be automated in a cron job or something like that).

How I think it will work:

  • When a crawler see your hashbang url, it will try to reach the ?_escaped_fragment_= URL. As we have actual HTML files on those folders, the Firebase will serve then and not redirect to index.html therefore the HTML read by crawler will be the cached version and not the AngularJS one.

To achieve that we need to create a scheduled job that runs the prerender for every pages, saves that folder and perform the firebase deploy.

As firebase deploy do not support partial deployment (sync or incremental ones) we should maintain an updated copy of our deployment on the server that will be responsible for this process.

I will try setup that and I will let you know if it works.

@srk9
Copy link

srk9 commented Feb 26, 2016

Can you please allow us to set "X-Prerender-Token" like we can other header keys???
https://www.firebase.com/docs/hosting/guide/full-config.html
https://prerender.io/install-token

@ghost
Copy link

ghost commented Sep 13, 2017 via email

@Birowsky
Copy link

Birowsky commented Sep 13, 2017

@megamindbrian is it implied that the functions have access to the hosted files? Is it documented anywhere? Thanx anyways!

@ghost
Copy link

ghost commented Sep 13, 2017 via email

@ghost
Copy link

ghost commented Sep 13, 2017 via email

@ghost
Copy link

ghost commented Sep 13, 2017 via email

@Birowsky
Copy link

Sorry, I still don't see a proper introduction of how the functions are conceptually connected to the hosted files. If you care to explain, I got some points for you: https://stackoverflow.com/q/46192570/592641

@ghost
Copy link

ghost commented Sep 13, 2017 via email

@Birowsky
Copy link

@megamindbrian I just tried fs.readFileSync('./index.html') but unfortunately, the file is not there. I was also hoping to find the hosted files in some implicitly generated storage bucket, no luck. How would you proceed?

@mbleigh
Copy link
Contributor

mbleigh commented Sep 13, 2017

If you nest your Hosting public directory inside your functions directory, it will be available there.

@ghost
Copy link

ghost commented Sep 13, 2017

@Birowsky Yup, here is how I am reading a file from a cloud function, e.g index.js:

const page = fs.readFileSync(__dirname + '/facebook-meta.html').toString();

But if your project layout is:

project/
project/src (<- actual source of app)
project/functions ( <- firebase functions)
project/dist (<- build output)

You will need to copy the relevant files out of /dist in to /functions

@tofanelli
Copy link

This issue has almos 3 years (so far) and still no luck at this point????

@ghost
Copy link

ghost commented Sep 14, 2017 via email

@mbleigh
Copy link
Contributor

mbleigh commented Sep 15, 2017 via email

@ghost
Copy link

ghost commented Sep 15, 2017

@mbleigh Can you use cloud functions on the root of a firebase domain, yet?

@mbleigh
Copy link
Contributor

mbleigh commented Sep 15, 2017 via email

@Yatima-Kagurazaka
Copy link

@mbleigh

This is a more robust and generalized solution that allows for all kinds of cool things!

SSR makes our system more complex 😢
I think prerendering is cooler not always but often 💡
e.g. Facebook OGP, Twitter Cards, SEO for non-Google

@judewang
Copy link

judewang commented Oct 17, 2017

@mbleigh @megamindbrian Thank you for your messages. I have made my hosting directing every requests to my function and response index.html which is hosted in functions/build/index.html to clients. But I don't know how to confirm is a request coming from FaceBot? I have tried using facebook debugging tools to access my website's url, I supposed the cloud function would be triggered, but it wasn't. I'm not familiar with back-end development, can you give me some hint? Thanks.

@ghost
Copy link

ghost commented Oct 17, 2017 via email

@ghost
Copy link

ghost commented Oct 17, 2017 via email

@judewang
Copy link

judewang commented Oct 17, 2017

@megamindbrian Function was triggered if I access my website with browser. But it wasn't triggered after using facebook tool to fetching the page's data.

@merlinnot
Copy link
Contributor

@judewang take a look at https://firebase.google.com/docs/hosting/functions#when_is_cached_content_served

For a quick-and-dirty test you may try to add some random query parameter to the tested URL.

@TheRoccoB
Copy link

So the initial question was how to use prerender. This solution doesn't solve the prerender integration problem, but it does solve open graph for a single page app.

  1. In my build script, I copy public/index.html to functions/hosting/index.html
  2. In firebase.json I add a rewrites rule to point to a cloud function called "host"
"hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "host"
      }
    ]
  }
  1. I define a cloud function called host. In most cases this just returns the index.html file that i copied over to functions/hosting/index.html, but if the agent is one of the known open graph parsers, I return database data in open graph format based on the route.
exports.host = functions.https.onRequest((req, res) => {
  var userAgent = req.headers['user-agent'];
  if (userAgent.startsWith('facebookexternalhit/1.1') ||
    userAgent === 'Facebot' ||
    userAgent.startsWith('Twitterbot')){

    //getOpenGraph() parses the path, and gets some data from the firebase database to construct open graph data.
    // eg: <meta property="og:description" content="My super cool webpage." /> <meta property="og:title"...

    res.status(200).send(getOpenGraph(req.path));
  }
  else{
    //optional - turn on caching: res.set('Cache-Control', 'public, max-age=300, s-maxage=600');
    res.status(200).send(fs.readFileSync('./hosting/index.html').toString());
  }
});

I think that's it. Hope this helps some folks!

@Pushplaybang
Copy link

I have to say this is disappointing, newer competitors have this down, such as https://www.netlify.com/features/, that definitely make it more attractive for web apps that need the SEO / Social integration.

Firebase is killing it for mobile / react native, and I'm really enjoying it as a platform overall, but this is a pretty big flaw for web apps IMO.

@mbleigh
Copy link
Contributor

mbleigh commented Jan 5, 2018

In general we've found that content that needs prerendering is also content that is best served by server-side rendering (for performance and first-load reasons). Generic prerendering is not on our immediate roadmap for this reason.

That being said, we are listening to the feedback about wanting the functions integration to be more flexible to allow "sometimes" function execution. Since Firebase Hosting relies heavily on CDN caching this kind of flexibility is difficult to achieve technically for us. We will continue to listen to feedback and try to find ways to make the platform better for your use case. 😄

@ghost
Copy link

ghost commented Jan 6, 2018 via email

@Pushplaybang
Copy link

@mbleigh isn't this standpoint somewhat opposed to the ethos of serverless, and using a BaaS / FaaS provider like firebase? With the trend to towards SPA's over the last few years, this is a fairly common use case, so much so that it's been tackled by competitors like netlify and roast for instance. While they're smaller, for hosting this just makes sense, providing faster load times, along with critical discoverability and shareability.

Rather than adding additional development and maintenance overhead for customers, an optional prerender service or at the very least, the ability to integrate with a third-party service such as prerender.io would be a vast improvement.

Firebase really is a great platform but seems more mobile orientated, with hosting being the only lacklustre part of it for me.

Thanks for the prompt response.

@cleverplatypus
Copy link

cleverplatypus commented Apr 14, 2018

@mbleigh

In general we've found that content that needs prerendering is also content that is best served by server-side rendering (for performance and first-load reasons).

Aside from @Pushplaybang's spot-on argument, I have to disagree with your argument. For one thing, it's up to the application developer (i.e. not to you guys) to take decisions in this area. Mere page performance considerations must be balanced with other equally important architectural decisions.

Single-page apps or sections of apps have to resort to some degree of client-side rendering and unfortunately crawlers, including google's own, are not very good yet at indexing such pages. I had to resort to PrerenderIO after months of failed attempts to let google index my websites properly, something that forced me to keep an express.js server based approach, just for the indexing issue.

Think of a website which has a /product/**.html page that renders ANY product depending on the client side detected deep url. The rationale behind this design is that loading an actual separate page for a product, even keeping into account browser and cdn caching, is not as smooth from the UX perspective as loading another product's data and rendering it while changing the url. Customers spend most of their time on product pages when browsign-to-buy while on an e-commerce website and often navigate to other products via "related products" links or in-page ajax searches links.

We are stuck with the absurd (IMHO) escaped_fragment mechanism lest we get penalized for cloaking... is Google finding hard to hire engineers with neat solutions to this ubiquitous issue??

I find even the total absence of a website/webapp indexing section in the documentation unjustifiable.
Mobile apps might dominate the consumer market but how about B2B? Most office departments operate on desktop computers. Indexing desktop websites to reach R&D or purchase departments is not a "nice to have", it's critical for B2B supplier businesses.

If Firebase/Google are not interested in this because flashy apps running on shiny gadgets make more revenue, it would be nice to know it; 4 years of giving evasive answers to loyal technology adopters are quite insulting to anyone's intelligence.

Ranty? Yes, but I'm the one having to justify additional infrastructure costs additional development times and unexpected behaviours of crawlers to my customers.

@Pushplaybang
Copy link

four years of this issue being open does seem a bit silly. @cleverplatypus - couldn't agree more with your sentiments.

@mbleigh
Copy link
Contributor

mbleigh commented May 7, 2018

This problem area overall isn't something we've stopped thinking about, but we still do not have any immediate plans for escaped fragment prerendering.

I recognize that there are definitely times when a static Single-Page App can benefit from prerendering; however, I still believe that in the majority of (but not all) cases of these types of sites are better yet served by server-side rendering that can bootstrap the SPA from any URL.

Our goal is to make Firebase Hosting a fantastic platform to deliver all kinds of web experiences. While I appreciate the frank and impassioned feedback provided in this thread, we do have limited resources and have to prioritize work that we think will have the largest impact for our customer base overall. If you want to help change our mind about prioritization of a feature that you feel strongly about, the best way is to file a feature request -- these are tallied up and help guide us towards work that is demanded by our developer community.

I'm going to close this thread since I don't think there's really anywhere left for the conversation to go, but I'd encourage anyone who is not well-served by our Cloud Functions integration to file a feature request for prerendering so that we can directly see how large the demand is!

Thanks for using Firebase Hosting, all 😸

@firebase firebase locked as resolved and limited conversation to collaborators May 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.