问题
I just finished building a PWA using Ionic. Now i am stuck in making PWA SEO enabled.
Since in ionic there is #(Hash location strategy) enabled in ionic and this results in # in all of the urls which doesn't help at all in SEO.
So to remove # I tried setting Path location strategy {locationStrategy: 'path'} in AppModule. This removes the # from the url. But when I try to refresh it or go directly to a url, it returns 'Cannot GET /url'
Few things I read for this problem is to rewrite to index.html in every request made Or try something as follows in node express.
app.get('*', (req, res, next) => {
if ((req.url.indexOf('#') > -1) ||
((req.url.lastIndexOf('.') === -1) ||
(req.url.indexOf('/', req.url.lastIndexOf('.')) > -1))) {
req.url = `/#${req.url}`;
}
next();
});
Both the above will not solve my problem because if I want to access a url directly i.e.. localhost/a/b . The above solutions will rewrite to localhost/home(Base URL) which I don't want.
回答1:
Got it working myself.
So here is the list of things which I did.
Add the following code to each of the page for which you want to add description, keywords
ionViewWillEnter(){ try{ document.querySelector("meta[name='description']").remove(); } catch (e){ } try{ document.querySelector("meta[name='keywords']").remove(); } catch (e){ } var description = document.createElement('meta'); description.name = "description"; description.content = "I am a description"; document.getElementsByTagName('head')[0].appendChild(description); var keywords = document.createElement('meta'); keywords.name = "keywords"; keywords.content = "Code, Learn, Respect"; document.getElementsByTagName('head')[0].appendChild(keywords); }
Now we need to remove # in path of every url because SEO rejects the urls with # in them. In App Module , add {locationStrategy: 'path'} to your App Module as follows :
IonicModule.forRoot(MyApp, { locationStrategy: 'path' })
Now # is removed from the url. But when you refresh or directly access the url, this wont work because this is expected behaviour for any SPA Because when you refresh the page , server tries to find the page linked to the URL. For eg: if you hit localhost/abc , then server tries to find abc/index.html which actually doesn't exist.So to resolve this , you have wrote configurations on my server i.e to point every request to index.html . I am using node express server to deploy your pwa. Use the following code to route every request to index.html -
var express = require('express'); var path = require('path') var app = express(); app.use(express.static(path.resolve(__dirname, "www"))); app.use('/*', function(req, res){ res.sendFile(__dirname+ '/www' + '/index.html'); }); app.set('port', process.env.PORT || 3000); app.listen(app.get('port'), function() { console.log("listening to Port", app.get("port")); });
- Also you need to put base href in index.html as '/'.
回答2:
IONIC with SSR (Server Side Rendering) integrated with Firebase Hosting + Cloud Functions + Prerender.io
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);
来源:https://stackoverflow.com/questions/48718349/seo-in-ionic-pwa