Este blog está hecho usando un theme llamado gatsby-theme-novela, en dicho tema no incluye los botones para compartir en redes sociales.
Para poder agregarlos como un componente de React, se debe editar la vista que contiene el template que renderisa un artículo individual.
Buscando en internet encontré el proyecto react-custom-share
Para instalarlo usa
1yarn add react-custom-share2yarn add emotion3yarn add react-icons
Acorde a la ubicaciíon del archivo a modificar en el theme, creé el siguiente directorio dentro de la carpeta `src“
1src2 @narrative3 gatsby-theme-novela4 template5 article.template.tsx
Dentro del archivo, en caso de copiarlo completo se deben modificar los imports con la ubicación de la dependencia.
Luego agregé lo siguiente
1// import icons2import { FaTwitter, FaFacebook, FaEnvelope, FaLinkedin } from "react-icons/fa";34// import react-custom-share components5import { ShareButtonIconOnly, ShareBlockStandard } from "react-custom-share";
1const shareBlockProps = {2 url: "https://javierfonseca.me" + article.slug,3 button: ShareButtonIconOnly,4 buttons: [5 { network: "Twitter", icon: FaTwitter },6 { network: "Facebook", icon: FaFacebook },7 { network: "Email", icon: FaEnvelope },8 { network: "Linkedin", icon: FaLinkedin }9 ],10 text: article.title,11 longtext: article.excerpt12 };
Luego ubiqué el siguiente código dentro del componente que renderiza el contenido del artículo
1<ShareBlockStandard {...shareBlockProps} />
Para validar los cambios y que ni haya habido errores en el código, reinicié el servidor usando
1gatsby develop
Ya con esto Gatsby puede hacer shadowing del template del artículo y mostrará los nuevos cambios.
Acá muestro los cambios al archivo completo
1import React, { useRef, useState, useEffect } from "react";2import styled from "@emotion/styled";3import throttle from "lodash/throttle";4import { graphql, useStaticQuery } from "gatsby";56import Layout from "@narative/gatsby-theme-novela/src/components/Layout";7import MDXRenderer from "@narative/gatsby-theme-novela/src/components/MDX";8import Progress from "@narative/gatsby-theme-novela/src/components/Progress";9import Section from "@narative/gatsby-theme-novela/src/components/Section";10import Subscription from "@narative/gatsby-theme-novela/src/components/Subscription";1112import mediaqueries from "@narative/gatsby-theme-novela/src/styles/media";13import { debounce } from "@narative/gatsby-theme-novela/src/utils";1415import ArticleAside from "@narative/gatsby-theme-novela/src/sections/article/Article.Aside";16import ArticleHero from "@narative/gatsby-theme-novela/src/sections/article/Article.Hero";17import ArticleControls from "@narative/gatsby-theme-novela/src/sections/article/Article.Controls";18import ArticlesNext from "@narative/gatsby-theme-novela/src/sections/article/Article.Next";19import ArticleSEO from "@narative/gatsby-theme-novela/src/sections/article/Article.SEO";20import ArticleShare from "@narative/gatsby-theme-novela/src/sections/article/Article.Share";2122import { Template } from "@narative/gatsby-theme-novela/src/types";2324// import icons25import { FaTwitter, FaFacebook, FaEnvelope, FaLinkedin } from "react-icons/fa";2627// import react-custom-share components28import { ShareButtonIconOnly, ShareBlockStandard } from "react-custom-share";2930const siteQuery = graphql`31 {32 allSite {33 edges {34 node {35 siteMetadata {36 name37 }38 }39 }40 }41 }42`;4344const Article: Template = ({ pageContext, location }) => {45 const contentSectionRef = useRef<HTMLElement>(null);4647 const [hasCalculated, setHasCalculated] = useState<boolean>(false);48 const [contentHeight, setContentHeight] = useState<number>(0);4950 const results = useStaticQuery(siteQuery);51 const name = results.allSite.edges[0].node.siteMetadata.name;5253 const { article, authors, mailchimp, next } = pageContext;5455 const shareBlockProps = {56 url: "https://javierfonseca.me" + article.slug,57 button: ShareButtonIconOnly,58 buttons: [59 { network: "Twitter", icon: FaTwitter },60 { network: "Facebook", icon: FaFacebook },61 { network: "Email", icon: FaEnvelope },62 { network: "Linkedin", icon: FaLinkedin }63 ],64 text: article.title,65 longtext: article.excerpt66 };6768 useEffect(() => {69 const calculateBodySize = throttle(() => {70 const contentSection = contentSectionRef.current;7172 if (!contentSection) return;7374 /**75 * If we haven't checked the content's height before,76 * we want to add listeners to the content area's77 * imagery to recheck when it's loaded78 */79 if (!hasCalculated) {80 const debouncedCalculation = debounce(calculateBodySize);81 const $imgs = contentSection.querySelectorAll("img");8283 $imgs.forEach($img => {84 // If the image hasn't finished loading then add a listener85 if (!$img.complete) $img.onload = debouncedCalculation;86 });8788 // Prevent rerun of the listener attachment89 setHasCalculated(true);90 }9192 // Set the height and offset of the content area93 setContentHeight(contentSection.getBoundingClientRect().height);94 }, 20);9596 calculateBodySize();97 window.addEventListener("resize", calculateBodySize);9899 return () => window.removeEventListener("resize", calculateBodySize);100 }, []);101102 return (103 <Layout>104 <ArticleSEO article={article} authors={authors} location={location} />105 <ArticleHero article={article} authors={authors} />106 <ArticleAside contentHeight={contentHeight}>107 <Progress contentHeight={contentHeight} />108 </ArticleAside>109 <MobileControls>110 <ArticleControls />111 </MobileControls>112 <ArticleBody ref={contentSectionRef}>113 <MDXRenderer content={article.body}>114 <ArticleShare />115 </MDXRenderer>116 <Section narrow>117 <p style={center}>Share</p>118 <ShareBlockStandard {...shareBlockProps} />119 </Section>120 </ArticleBody>121 {mailchimp && article.subscription && <Subscription />}122 {next.length > 0 && (123 <NextArticle narrow>124 <FooterNext>More articles from {name} </FooterNext>125 <ArticlesNext articles={next} />126 <FooterSpacer />127 </NextArticle>128 )}129 </Layout>130 );131};132133export default Article;134135const center = {136 textAlign:"center",137 paddingBottom: "10px"138};139140const MobileControls = styled.div`141 position: relative;142 padding-top: 60px;143 transition: background 0.2s linear;144 text-align: center;145 ${mediaqueries.tablet_up`146 display: none;147 `}148`;149150const ArticleBody = styled.article`151 position: relative;152 padding: 160px 0 35px;153 padding-left: 68px;154 transition: background 0.2s linear;155 ${mediaqueries.desktop`156 padding-left: 53px;157 `}158159 ${mediaqueries.tablet`160 padding: 70px 0 80px;161 `}162 ${mediaqueries.phablet`163 padding: 60px 0;164 `}165`;166167const HoritzontalRule = styled.div`168 position: relative;169 margin: 140px auto 50px;170 border-bottom: 1px solid ${p => p.theme.colors.horizontalRule};171 ${mediaqueries.tablet`172 margin: 60px auto;173 `}174 ${mediaqueries.phablet`175 display: none;176 `}177`;178179const NextArticle = styled(Section)`180 display: block;181`;182183const FooterNext = styled.h3`184 position: relative;185 opacity: 0.25;186 margin-bottom: 100px;187 font-weight: 400;188 padding-top: 30px;189 color: ${p => p.theme.colors.primary};190 ${mediaqueries.tablet`191 margin-bottom: 60px;192 `}193 &::after {194 content: '';195 position: absolute;196 background: ${p => p.theme.colors.grey};197 width: 100%;198 height: 1px;199 right: 0;200 top: 11px;201 ${mediaqueries.tablet`202 width: ${(600 / 1140) * 100}%;203 `}204 ${mediaqueries.phablet`205 width: ${(400 / 1140) * 100}%;206 `}207 ${mediaqueries.phone`208 width: 90px209 `}210 }211`;212213const FooterSpacer = styled.div`214 margin-bottom: 65px;215`;
Share