Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 75bf199

Browse files
committed
chore(docs.angularjs.org): serve snapshots for googlebot
This commit restores serving the plain partials (content) when a docs page is accessed with ?_escaped_fragment_=. The Google Ajax Crawler accesses these urls when the page has `<meta type="fragment" content="!">` is set. During the migration to Firebase, this was lost, which resulted in Google dropping the docs almost completely from the index. We are using a Firebase cloud function to serve the partials. Since we cannot access the static hosted files from the function, we have to deploy them as part of the function directory instead, from which they can be read. Related to #16432 Related to #16417
1 parent 9196c80 commit 75bf199

File tree

7 files changed

+4376
-9
lines changed

7 files changed

+4376
-9
lines changed

Gruntfile.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ var semver = require('semver');
1313
var exec = require('shelljs').exec;
1414
var pkg = require(__dirname + '/package.json');
1515

16+
var docsScriptFolder = 'scripts/docs.angularjs.org-firebase';
17+
1618
// Node.js version checks
1719
if (!semver.satisfies(process.version, pkg.engines.node)) {
1820
reportOrFail('Invalid node version (' + process.version + '). ' +
@@ -165,7 +167,8 @@ module.exports = function(grunt) {
165167
tmp: ['tmp'],
166168
deploy: [
167169
'deploy/docs',
168-
'deploy/code'
170+
'deploy/code',
171+
docsScriptFolder + '/functions/html'
169172
]
170173
},
171174

@@ -341,7 +344,17 @@ module.exports = function(grunt) {
341344
src: '**',
342345
dest: 'deploy/docs/',
343346
expand: true
344-
}
347+
},
348+
{
349+
src: ['build/docs/index-production.html'],
350+
dest: docsScriptFolder + '/functions/content',
351+
expand: true,
352+
flatten: true
353+
},
354+
{
355+
cwd: 'build/docs',
356+
src: 'partials/**',
357+
dest: docsScriptFolder + '/functions/content',
345358
expand: true
346359
}
347360
]

lib/grunt/utils.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,13 @@ module.exports = {
297297
// Our Firebase projects are in subfolders, but Travis expects them in the root,
298298
// so we need to modify the upload folder path and copy the file into the root
299299
firebaseDocsJsonForTravis: function() {
300-
var docsScriptFolder = 'scripts/docs.angularjs.org-firebase/';
300+
var docsScriptFolder = 'scripts/docs.angularjs.org-firebase';
301301

302-
var fileName = docsScriptFolder + 'firebase.json';
302+
var fileName = docsScriptFolder + '/firebase.json';
303303
var json = grunt.file.readJSON(fileName);
304304

305305
json.hosting.public = 'deploy/docs';
306+
json.functions.source = docsScriptFolder + '/functions';
306307

307308
grunt.file.write('firebase.json', JSON.stringify(json));
308309
}

scripts/docs.angularjs.org-firebase/firebase.json

+8-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@
2323
"destination": "/index-production.html"
2424
},
2525
{
26-
"source": "**/*!(.jpg|.jpeg|.gif|.png|.html|.js|.map|.json|.css|.svg|.ttf|.txt|.woff|.woff2|.eot|.xml)",
27-
"destination": "/index-production.html"
26+
"source": "**/*!(.@(jpg|jpeg|gif|png|html|js|map|json|css|svg|ttf|txt|woff|woff2|eot|xml))",
27+
"function": "sendFile"
2828
}
2929
]
30+
},
31+
"functions": {
32+
"predeploy": [
33+
"npm --prefix $RESOURCE_DIR run lint"
34+
]
3035
}
31-
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
'use strict';
2+
3+
const functions = require('firebase-functions');
4+
const fs = require('fs');
5+
6+
const BROWSER_CACHE_DURATION = 60 * 60;
7+
const CDN_CACHE_DURATION = 60 * 60 * 12;
8+
9+
const headers = {
10+
'Cache-Control': `public max-age=${BROWSER_CACHE_DURATION} s-maxage=${CDN_CACHE_DURATION}`
11+
};
12+
13+
const buildSnapshot = data => `<!DOCTYPE html>
14+
<html lang="en">
15+
<head>
16+
<meta charset="utf-8" />
17+
<meta name="viewport" content="width=device-width, initial-scale=1">
18+
<base href="/">
19+
</head>
20+
<body>
21+
${data}
22+
</body>
23+
</html>`;
24+
25+
function sendFile(request, response) {
26+
27+
const snapshotRequested = typeof request.query._escaped_fragment_ !== 'undefined';
28+
const filePath = `content/${snapshotRequested ? `partials${request.path}` : 'index-production'}.html`;
29+
30+
if (snapshotRequested) {
31+
fs.readFile(filePath, {encoding: 'utf8'}, (error, data) => {
32+
if (error) {
33+
response
34+
.status(404)
35+
.end();
36+
} else {
37+
response
38+
.set(headers)
39+
.send(buildSnapshot(data));
40+
}
41+
});
42+
} else {
43+
response
44+
.set(headers)
45+
.sendFile(filePath, {root: __dirname});
46+
}
47+
}
48+
49+
exports.sendFile = functions.https.onRequest(sendFile);

0 commit comments

Comments
 (0)