Objetivo: modificar las metaetiquetas de Open Graph cuando los rastreadores web visiten diferentes rutas.
Sé que Angular2 4.0.0 tiene un MetaService, y siempre hay jQuery, pero los rastreadores web, excepto Googlebot, no ejecutan Javascript, por lo que es un poco inútil para mi propósito. Mientras que Angular Universal suena como una exageración para cambiar un par de metaetiquetas.
Hasta ahora, mi solución es copiar y pegar el index.html compilado en /dist a index.ejs y modificar los campos necesarios. ¿Es posible integrar el flujo de trabajo con el proceso de compilación angular-cli cambiando el punto de entrada de index.html a index.ejs? Si no, ¿cuáles son las alternativas que debería explorar?
En mi index.ejs:
<meta property="og:url" content="<%= url %>" />En mi ruta Express index.js:
res.render('index', { url: site_url, });En mi server.js:
app.set('views', path.join(__dirname, '/dist')); app.set('view engine', 'ejs');Por favor, absténgase de responder a la versión actual de @angular/cli (compatible con v1.0.1).
Algunas discusiones relacionadas: Agregue opciones de personalización para HtmlWebpackPlugin #3338 Lógica de plantilla condicional en index.html para beta.11-webpack #1544 Proporcione la configuración para cambiar el nombre de index.html en la carpeta dist #2241
Pude resolver esto usando Nunjucks para renderizar plantillas servidas a través de Angular Universal. Estoy seguro de que también es posible usar otros motores como EJS. Aquí están las partes relevantes de mi server.ts:
import * as dotenv from 'dotenv'; dotenv.config(); import 'zone.js/dist/zone-node'; import 'reflect-metadata'; import * as nunjucks from 'nunjucks'; import { renderModuleFactory } from '@angular/platform-server'; import { enableProdMode } from '@angular/core'; import * as express from 'express'; import { join } from 'path'; import { readFileSync } from 'fs'; // Faster server renders w/ Prod mode (dev mode never needed) enableProdMode(); // Express server const app = express(); const PORT = process.env.PORT || 4201; const DIST_FOLDER = join(process.cwd(), 'dist'); // Our index.html we'll use as our template const template = readFileSync(join(DIST_FOLDER, 'index.html')).toString(); // * NOTE :: leave this as require() since this file is built Dynamically from webpack const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist-server/main.bundle'); const { provideModuleMap } = require('@nguniversal/module-map-ngfactory-loader'); nunjucks.configure(DIST_FOLDER, { autoescape: true, express: app, }); app.engine('html', (_, options, callback) => { renderModuleFactory(AppServerModuleNgFactory, { // Our index.html document: template, url: options.req.url, // DI so that we can get lazy-loading to work differently (since we need it to just instantly render it) extraProviders: [ provideModuleMap(LAZY_MODULE_MAP) ] }).then(html => { callback(null, html); }); }); app.set('view engine', 'html'); // Server static files from dist folder app.get('*.*', express.static(DIST_FOLDER)); // All regular routes use the Universal engine // You can pass in server-side values here to have Nunjucks render them app.get('*', (req, res) => { res.render('index', { req, yourVar: 'some-value' }); }); // Start up the Node server app.listen(PORT, () => { console.log(`Node server listening on http://localhost:${PORT}`); });