在Next.js中如何实现文章第3个段落后插入Google Adsense广告
实现方案
方法1:客户端渲染后操作DOM(最简单,适合纯客户端渲染的内容)
核心逻辑是等文章内容渲染完成后,直接操作DOM节点插入广告,实现步骤如下:
- 给承载内容的
Card.Body绑定ref,用于获取渲染后的真实DOM节点 - 用
useEffect监听文章内容的变化,确保内容完全渲染后再执行插入逻辑 - 统计段落数量,判断是否满足插入条件,同时做去重处理避免重复插入广告
代码示例:
import { useRef, useEffect, useState } from 'react'; import Card from 'react-bootstrap/Card'; const ArticleContent = ({ data }) => { const contentRef = useRef(null); const [paragraphCount, setParagraphCount] = useState(0); useEffect(() => { if (!contentRef.current || !data?.news?.content) return; // 获取所有段落节点,统计数量 const paragraphs = contentRef.current.querySelectorAll('p'); const count = paragraphs.length; setParagraphCount(count); // 段落数不足3则不插入广告 if (count < 3) return; // 先移除之前插入的广告,避免内容更新后重复插入 const existedAd = document.getElementById('adsense-after-p3'); if (existedAd) existedAd.remove(); // 创建广告容器 const adContainer = document.createElement('div'); adContainer.id = 'adsense-after-p3'; adContainer.style.margin = '20px 0'; // 可根据需求自定义样式 // 填入你自己的Adsense广告代码 adContainer.innerHTML = ` <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-你的Adsense发布商ID" data-ad-slot="你的广告位ID" data-ad-format="auto" data-full-width-responsive="true"></ins> `; // 插入到第3个段落后面(DOM索引从0开始,所以第3个是索引2) paragraphs[2].after(adContainer); // 触发广告渲染 try { (window.adsbygoogle = window.adsbygoogle || []).push({}); } catch (e) { console.error('广告加载失败', e); } }, [data?.news?.content]); // 文章内容更新时重新执行逻辑 return ( <Card.Body ref={contentRef} dangerouslySetInnerHTML={{ __html: data.news.content }} /> ); }; export default ArticleContent;
注意:你需要提前在项目中引入Adsense的官方脚本,可以加在_document.js的头部,避免脚本未加载导致广告渲染失败。这种方案逻辑只会在客户端执行,不会影响服务端渲染内容,不会出现hydration不匹配问题。
方法2:预处理HTML字符串(适合SSR/SSG场景,性能更好)
如果你不想操作渲染后的DOM,可以在把HTML字符串传入dangerouslySetInnerHTML之前,直接在字符串层面插入广告代码,服务端就可以完成处理。这里用轻量的HTML处理库cheerio实现:
- 先安装依赖:
npm install cheerio - 组件代码:
import cheerio from 'cheerio'; import Card from 'react-bootstrap/Card'; import { useEffect } from 'react'; const ArticleContent = ({ data }) => { if (!data?.news?.content) return <Card.Body />; // 加载原始HTML内容 const $ = cheerio.load(data.news.content); const paragraphs = $('p'); const paragraphCount = paragraphs.length; // 段落数满足条件则插入广告代码 if (paragraphCount >= 3) { const adHtml = ` <div id="adsense-after-p3" style="margin:20px 0"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-你的Adsense发布商ID" data-ad-slot="你的广告位ID" data-ad-format="auto" data-full-width-responsive="true"></ins> </div> `; // 插入到第3个p标签后面 paragraphs.eq(2).after(adHtml); } // 拿到处理完成的HTML字符串 const processedContent = $.html(); // 客户端加载完成后触发广告渲染 useEffect(() => { try { (window.adsbygoogle = window.adsbygoogle || []).push({}); } catch (e) {} }, []); return ( <Card.Body dangerouslySetInnerHTML={{ __html: processedContent }} /> ); }; export default ArticleContent;
这种方式预处理后的内容可以直接在服务端渲染,不需要等到客户端加载完成才显示广告,性能更优。
内容的提问来源于stack exchange,提问作者Russell Harrower
相关产品推荐
相关产品推荐

