gatsbyjs(静的サイトジェネレーター)を利用して、ブログを作りましたが、①記事が表示されない、②Google adsenseを挿入しようと思うとエラーが発生する問題が起き、ご助言いただきたくお願いします。
やりたいこと
マークダウンファイル(記事)をにadsenseコードを代入した後(コード内のinsertAdsense)、componentDIdMountでadsbygoogleをpushし、記事内にアドセンス広告を表示したい
エラー内容
下記の3通りの出来事が起きており、
①問題なく記事内に広告が設置される
②記事タイトル等は表示されるが、記事コンテンツが表示されない
③記事が表示されず、画面が真っ白になる
②、③のエラー時には、「"adsbygoogle.push() error: All ins elements in the DOM with class=adsbygoogle already have ads in them."」というエラーが表示されます。
②、③が起きた場合でも、リロードすればきちんと表示されるので、コード実行の順番などが原因ではないかと思っています。(おそらく、dangerouslySetInnerHTMLで記事コンテンツが完全にセットされる前に、componentDidMountが起きているから②・③が起きているのか?とも思っておりますが、うまく行かず、、、)
問題が起きているサイト
コード(抜粋)
post.js側で、
記事コンテンツを取得(post)
⇨ insertAdsenseでマークダウンファイルのコンテンツ内にアドセンスコードを挿入
⇨ componentDidMountでadsbygoogleをpush
という大きな流れです。
post.js
react
1 2 3import AdsenseRectangle from "../components/InsertAdsense" 4import { insertAdsense } from "../components/InsertAdsense" 5 6 7 8class BlogPostTemplate extends React.Component { 9 constructor(props) { 10 super(props) 11 const post = this.props.data.markdownRemark 12 const slug = this.props.pageContext 13 const { temp1, numberOfAds } = insertAdsense(post.html, slug) 14 this.state = { numberOfAdsense: numberOfAds } 15 } 16 17 componentDidMount() { 18 if (window) 19 for (let i = 0; i < this.state.numberOfAdsense + 1; i++) { 20 (window.adsbygoogle = window.adsbygoogle || []).push({}); 21 } 22 } 23 24 render() { 25 const post = this.props.data.markdownRemark 26 27 const siteTitle = this.props.data.site.siteMetadata.title 28 const { relatedPosts, slug } = this.props.pageContext 29 30 const { post2, temp2 } = insertAdsense(post.html, slug) 31 32 const { title, description, date, category, tags } = post.frontmatter 33 34 const sizes = post.frontmatter.featuredImage 35 ? post.frontmatter.featuredImage.childImageSharp.sizes 36 : 0 37 38 const { categories } = this.props.data.site.siteMetadata 39 const categoryObject = categories.find(cat => { 40 return cat.slug === category 41 }) 42 const categoryColor = categoryObject ? categoryObject.color : "#555" 43 44 return ( 45 <Layout location={this.props.location} title={siteTitle} pageAd={"true"}> 46 <SEO title={title} description={description || post.excerpt} /> 47 <Helmet> 48 <link 49 rel="canonical" 50 href={`https://englissu.com${this.props.location.pathname}`} 51 /> 52 </Helmet> 53 <PostJsonLd 54 title={title} 55 description={description || post.excerpt} 56 date={date} 57 url={this.props.location.href} 58 categorySlug={category} 59 /> 60 <Content> 61 <ContentMain> 62 <PostTitle>{title}</PostTitle> 63 <Labels> 64 <CategoryLabel slug={category} isLink="true" /> 65 {tags.map(({ tag }, index) => { 66 return <TagLabel key={index} slug={tags[index]} isLink="true" /> 67 })} 68 </Labels> 69 <PostDate>{date}</PostDate> 70 71 <FeaturedImage sizes={sizes} className="featured-image" /> 72 <PostContent 73 categoryColor={categoryColor} 74 categorySlug={category} 75 dangerouslySetInnerHTML={{ __html: post2 }} 76 77 <FollowBudge /> 78 <ShareButtons slug={slug} title={title} /> 79 </ContentMain> 80 81 <AdsenseRectangle slug={slug} /> 82 83 <aside> 84 <RelatedPosts posts={relatedPosts} /> 85 </aside> 86 </Content> 87 </Layout> 88 ) 89 } 90} 91 92export default BlogPostTemplate 93 94export const pageQuery = graphql` 95 query blogPostBySlug($slug: String!) { 96 site { 97 siteMetadata { 98 title 99 author 100 categories { 101 name 102 slug 103 color 104 } 105 } 106 } 107 108 markdownRemark(fields: {slug: {eq: $slug } }) { 109 id 110 excerpt(pruneLength: 160) 111 html 112 frontmatter { 113 title 114 description 115 date(formatString: "YYYY.MM.DD") 116 category 117 tags 118 featuredImage { 119 childImageSharp { 120 sizes(maxWidth: 630) { 121 ...GatsbyImageSharpSizes 122 } 123 } 124 } 125 } 126 } 127} 128`
insertAdsense.js
import React from 'react'; class Adsense extends React.Component { render() { return <div>{this.props.component}</div>; } } const Rectangle = (props) => { return ( <ins className="adsbygoogle" style={{ display: 'block' }} data-ad-client="ca-pub-" data-ad-slot="" data-ad-format="auto" data-full-width-responsive="true" key={'5-' + props.slug} /> ); }; const AdsenseRectangle = (props) => <Adsense component={<Rectangle slug={props.slug} />} /> export default AdsenseRectangle const parser = typeof DOMParser !== "undefined" && new DOMParser() export const insertAdsense = (html, slug) => { if (!parser) return html const dom = parser.parseFromString(html, "text/html") const eles = [].slice.call(dom.querySelectorAll(".adsense1, .adsense2, .adsense3, .adsense4")) const ad1 = ` <ins class="adsbygoogle" style="display: block;" data-ad-client="ca-pub-" data-ad-slot="" data-ad-format="auto" data-full-width-responsive="true" key={'1-' + ${slug}} ></ins> ` const ad2 = ` <ins class="adsbygoogle" style="display: block;" data-ad-client="ca-pub-" data-ad-slot="" data-ad-format="auto" data-full-width-responsive="true" key={'2-' + ${slug}} ></ins> ` const ad3 = ` <ins class="adsbygoogle" style="display: block;" data-ad-client="ca-pub-" data-ad-slot="" data-ad-format="auto" data-full-width-responsive="true" key={'3-' + ${slug}} ></ins> ` const ad4 = ` <ins class="adsbygoogle" style="display: block;" data-ad-client="ca-pub-" data-ad-slot="" data-ad-format="auto" data-full-width-responsive="true key={'4-' + ${slug}} ></ins> ` const ads = [ad1, ad2, ad3, ad4] const numberOfAds = eles.length; if (eles) { eles.map((ele, index) => (ele.innerHTML = ads[index])) } return { post2: dom.body.innerHTML, numberOfAds: numberOfAds } }
初心者の汚いコードで大変申し訳ございませんが、お力添えのほどよろしくお願いします。
あなたの回答
tips
プレビュー