Angular页面标题服务端设置需求:解决短信预览显示默认标题问题
解决Angular页面标题在短信预览中不显示的服务端方案
你遇到的问题本质是客户端渲染的局限性:短信预览的爬虫只会抓取初始HTML里的<title>标签,不会执行Angular的客户端JS代码,所以路由配置或Title服务设置的标题只会在浏览器加载后生效,爬虫根本看不到。要解决这个问题,必须让页面标题在服务端渲染阶段就注入到HTML中,下面是两种可行方案:
方案一:使用Angular Universal(服务端渲染SSR)
Angular Universal会在服务端为每个请求生成完整的HTML,包括对应路由的页面标题,爬虫抓取时能直接拿到正确的标题。
步骤:
- 安装Universal依赖
ng add @nguniversal/express-engine
- 保留原路由的title配置(比如你之前的写法):
{ path: 'prgw/digital', component: SelectedComponent, title: 'You\'ve been selected' }
- 修改服务端入口文件
server.ts,在渲染HTML时注入对应路由的标题:
import { Router, RouterModule } from '@angular/router'; import { renderModuleFactory } from '@angular/platform-server'; // 导入你的路由配置 import { routes } from './src/app/app-routing.module'; // ... 其他默认代码 app.get('*', (req, res) => { const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString(); const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main'); // 初始化路由并匹配当前请求路径 const routerInjector = RouterModule.forRoot(routes).injector; const router = routerInjector.get(Router); router.resetUrl(req.url); // 获取当前路由的标题 let pageTitle = '默认标题'; const activeRoute = router.routerState.root.firstChild; if (activeRoute) { // 优先取路由配置里的title if (activeRoute.snapshot.routeConfig?.title) { pageTitle = activeRoute.snapshot.routeConfig.title as string; } // 如果是动态title存在data里也可以取 else if (activeRoute.snapshot.data.title) { pageTitle = activeRoute.snapshot.data.title; } } // 渲染模块并替换title标签 renderModuleFactory(AppServerModuleNgFactory, { document: template, url: req.url, extraProviders: [ provideModuleMap(LAZY_MODULE_MAP), { provide: 'REQUEST', useValue: req }, { provide: 'RESPONSE', useValue: res }, ] }).then(html => { // 替换初始HTML中的默认title const finalHtml = html.replace(/<title>.*?<\/title>/, `<title>${pageTitle}</title>`); res.send(finalHtml); }); });
- 启动服务端渲染服务:
npm run dev:ssr
测试时可以用curl命令查看返回的HTML,确认<title>标签内容是否正确:
curl https://your-domain/prgw/digital
方案二:预渲染(Prerendering)
如果你的路由都是静态的(没有动态参数或需要实时数据的标题),可以用预渲染生成带正确标题的静态HTML文件,部署后爬虫直接抓取静态文件即可。
步骤:
- 确保路由配置中已经设置好title
- 执行预渲染命令:
ng run your-project-name:prerender
- 部署生成的
dist/browser目录下的静态文件即可。预渲染会为每个路由生成独立的HTML文件,每个文件里都包含对应路由的标题。
注意事项
- 如果标题是动态生成的(比如从接口获取),必须在服务端完成数据请求后再注入标题,不能依赖客户端请求。
- 测试时不要用浏览器直接访问(浏览器会执行JS覆盖标题),用curl或者在线爬虫预览工具查看返回的原始HTML。
内容的提问来源于stack exchange,提问作者Collin Williams
相关产品推荐
相关产品推荐

