Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Cloud Functions for Firebase to prerender pages for SEO?

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"}]
    
like image 972
Chaitanya Nettem Avatar asked Jun 01 '17 08:06

Chaitanya Nettem


3 Answers

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);
  });
};
like image 86
dot3 Avatar answered Jun 11 '23 15:06

dot3


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);
like image 31
Vinicius Carvalho Avatar answered Jun 11 '23 15:06

Vinicius Carvalho


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.

like image 29
Doug Stevenson Avatar answered Jun 11 '23 15:06

Doug Stevenson