How to use Cloud Functions for Firebase to prerender pages for SEO?
Asked Answered
B

3

9

The Cloud Functions for Firebase documentation here states that this can be done using cloud functions -

Prerendering for single page apps to improve SEO. This allows you to create dynamic meta tags for sharing across various social networks.

There are 2 questions I have:

  • Can someone explain with an example how pre-rendering is achieved?

  • How does this work in conjunction with Firebase Hosting? So let's say I have a webpage at xyz.com/salon/43 and in Firebase hosting I have a salon.html which is served in response to this request. Now in order to be able to prerender should I move from hosting to a cloud function which renders the webpage? In other words do I go from

    "rewrites": [{
        "source": "/salon/*",
        "destination": "/salon.html"}]
    

    to

    "rewrites": [{
        "source": "/salon", "function": "salon"}]
    
Bosun answered 1/6, 2017 at 8:10 Comment(0)
O
10

Two tasks: - Add the function to your hosting rewrite as in your example - Write the function to generate an html page

This tutorial provides a great example, with the following function as an example from a longer snippet:

const admin = require('firebase-admin');

function buildHtmlWithPost (post) {
  const string = '<!DOCTYPE html><head>' \
    '<title>' + post.title + ' | Example Website</title>' \
    '<meta property="og:title" content="' + post.title + '">' \
    '<meta property="twitter:title" content="' + post.title + '">' \
    '<link rel="icon" href="https://example.com/favicon.png">' \
    '</head><body>' \
    '<script>window.location="https://example.com/?post=' + post.id + '";</script>' \
    '</body></html>';
  return string;
}

module.exports = function(req, res) {
  const path = req.path.split('/');
  const postId = path[2];
  admin.database().ref('/posts').child(postId).once('value').then(snapshot => {
    const post = snapshot.val();
    post.id = snapshot.key;
    const htmlString = buildHtmlWithPost(post);
    res.status(200).end(htmlString);
  });
};
Oilskin answered 3/10, 2017 at 19:18 Comment(1)
Can we achieve the same using google app engine instead of google function?Complication
S
6

First of all, sorry for my poor English.

After searching through Deep Web (joking), I found the solution. And the coolest solution was that I was able to integrate my Pioneer Ionic application with Firebase Hosting using Cloud Functions.

After reading the following topic:

https://github.com/firebase/firebase-tools/issues/33

The @TheRoccoB user explains how to host the static Web application in Firebase Hosting and redirect traffic from a URL to Cloud Functions.

What I did was map the routes that I have to index as:

{
    "source": "/ shop / **",
    "function": "ssr"
},
{
    "source": "/ * / promotions / **",
    "function": "ssr"
}

Since "ssr" is the name of my function in Cloud Functions. So I used the library https://github.com/prerender/prerender-node to check if the request is from a google crowler, in case I redirect the request to a https://github.com/prerender/prerender server.

const prerender = express ();
prerender.use (cors);
prerender.use (
    require ('prerender-node')
    // .set ('prerenderServiceUrl', 'http: // localhost: 3000')
    .set ('prerenderToken', '** TOKEN **')
);
prerender.use (require ('prerender-node'). set ('beforeRender', function (req, done) {
    // do you need to do?
    console.log ('Rendering URL:', req.path);
done ();
}));
prerender.use (require ('prerender-node') set ('afterRender', function (err, req, prerender_res) {
    // do you need to do?
    console.log (req.path + 'rendering completed!');
    console.log ('Errors:', err);
}));
prerender.get ('*', (req, res) => {
    console.log ('Calling function for URL:', req.path);
    res.set ('Cache-Control', 'public, max-age = 300, s-maxage = 600');
    res.status (200) .send (fs.readFileSync ('./ www / index.html'). toString ());
});
exports.ssr = functions.https.onRequest (prerender);
Samellasameness answered 7/7, 2018 at 22:0 Comment(2)
Hi I didn't get res.status (200) .send (fs.readFileSync ('./ www / index.html'). toString ()); this part. I'm working on a Vue JS app where I want to use prerender.io but in my dist folder I got index.html no www.Cosmography
Hey, I'm @ the_roccob on github!! Thanks for sharing and expanding my response! I may implement this sometime on my site simmer.ioFungal
P
4

You are correct, you effectively rewrite your app's HTML page to point to a function instead of a static document. Then, when that page is accessed, your function will effectively generate the HTML that gets sent back to the browser. You are taking this opportunity to decide, at that very moment, what the contents of the HTML should be.

If the contents don't need to be generated on every single access (each of which costs money according to the billing rates shown on the pricing page), you'll also probably want to make use of caching to eliminate to serve cached, pre-rendered content from the Firebase Hosting CDNs.

Pozzy answered 2/6, 2017 at 0:18 Comment(3)
Can you please share a coding example?Cosmography
@Cosmography code example here: https://mcmap.net/q/828288/-is-it-possible-to-redirect-all-url-paths-to-the-root-handler-in-app-engine-in-a-nodejs-appTwoply
Thanks man for the link. But I mostly work with Vue. Moreover as Google bot stated using the latest Chrome engine I rarely think in near future we are going to need pretender or SSR. I just made an app in Vue and it's a spa. Believe it or not Google indexed it perfectly despite it having dynamic title, description. I'm simply amazed by the new Google bot rendering and indexing capabilityCosmography

© 2022 - 2024 — McMap. All rights reserved.