<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/bug.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>theGlitch</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fjalla+One&family=Open+Sans:ital,wght@0,300;1,300&family=Quattrocento&family=Source+Serif+4:ital,opsz@0,8..60;1,8..60&display=swap" rel="stylesheet">
<script type="module" crossorigin src="/assets/index-K-gY7Fqn.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-0ZvQpehw.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
None of the metatags are visible with curl. How can I make them dynamic for each article and visible?
My website How do I get the thumbnails to show up when the article links are shared on Lemmy? I tried metatags, changing the aspect ratio and the image format. Nothing seems to work. Here are some of the failed results.: !theglitch@lemmy.dbzer0.com Any help would be appreciated.
Article.tsx: ``` import React, {useEffect, useState, useContext } from "react" import { useParams, Link, useNavigate } from "react-router-dom" import { articlesData } from "../data/articles" import { styled } from "styled-components" import MetaTags from "../utils/MetaTags" import CopyLinkIconDark from "/src/assets/copyLinkDark.svg" import CopyLinkIconLight from "/src/assets/copyLinkLight.svg" import FacebookShareIconDark from "/src/assets/facebookShareDark.svg" import FacebookShareIconLight from "/src/assets/facebookShareLight.svg" import TwitterShareIconDark from "/src/assets/twitterShareDark.svg" import TwitterShareIconLight from "/src/assets/twitterShareLight.svg" import ThemeContext from "../utils/ThemeContext" import formatDate from "../utils/formatDate"
type articlesData = { id: number; articleUrl: string; category: string; img: string; alt: string; header: string; subhead: string; author: string; datePublished: Date; articleBody: string[]; }
const StyledHeroWrapper = styled.div position: relative;
const StyledLogo = styled.h2 position: absolute; font-size: 4rem; text-shadow: ${({ theme }) => theme.isDarkMode ? "1px 1px 5px rgba(0, 0, 0, 0.5)" : "1px 1px 5px rgba(255, 255, 255, 0.5)"}; top: -6.3rem; left: -1rem;
const StyledImg = styled.img max-width: 100%; margin: 0; border-radius: 5px; object-fit: cover;
const StyledHeadline = styled.h1 font-family: "Fjalla One", sans-serif; font-weight: 400; font-style: normal; font-size: 3rem; letter-spacing: -0.05em; transform: tranlateY(-20%); max-width: 90%; word-spacing: -0.05em; line-height: 3.4rem; margin: 0;
const StyledSubhead = styled.h3 font-family: "Source Serif 4", serif; font-optical-sizing: auto; font-weight: 400; font-style: normal; font-size: 1.5rem; letter-spacing: -0.05em; word-spacing: -0.05em; margin: 0; line-height: 1.5rem;
const StyledArticleInfo = styled.p font-family: "Open Sans", sans-serif; font-optical-sizing: auto; font-weight: 300; font-style: normal; font-variation-settings: "wdth" 100; text-transform: uppercase;
const StyledAuthor = styled(Link) color: ${({ theme }) => theme.isDarkMode ? "#9CE00C" : "#5200FF"}; margin-right: 1rem; text-decoration: none; &:hover { background-color: ${({ theme }) => theme.isDarkMode ? "#5200FF" : "#9CE00C"}; }
const StyledButtonWrapper = styled.div display: flex;
const StyledShareButton = styled.button display: flex; align-items: center; justify-content: center; width: 3rem; height: 3rem; border-radius: 50%; background-color: ${({ theme }) => theme.isDarkMode ? "#353535" : "#cacaca"}; margin-right: 1rem; border: none; &:hover { background-color: ${({ theme }) => theme.isDarkMode ? "#5200FF" : "#9CE00C"}; } a { width: 2rem; height: 2rem; display: flex; align-items: center; justify-content: center; }
const StyledShareImgIcon = styled.img width: 2rem; height: 2rem;
const StyledArticleBody = styled.p font-family: "Quattrocento", serif; font-weight: 400; font-style: normal; font-size: 1.2rem
const copyLink = async () => { try { await navigator.clipboard.writeText(window.location.href); alert('Link copied to clipboard!'); } catch (err) { console.error(err); alert('Failed to copy link to clipboard!'); } }
const Article: React.FC = () => { const { isDarkMode } = useContext(ThemeContext); const {articleUrl} = useParams() const [article, setArticle] = useState<articlesData | null>(null) const [isLoading, setIsLoading] = useState(true) useEffect(()=>{ const foundArticle = articlesData.find(articleObj => articleObj.articleUrl === articleUrl); setArticle(foundArticle ? foundArticle : null); setIsLoading(false) },[]) const navigate = useNavigate() let formattedDate = "" if(article){ formattedDate = formatDate(article.datePublished) } useEffect(()=>{ if(!article && !isLoading) { navigate('not-found') } }, [isLoading])
return (
<>
<MetaTags
title={article?.header || ""}
description={article?.subhead || ""}
imageUrl={article?.img || ""}
url={window.location.href}
/>
<main>
<StyledHeroWrapper>
<StyledLogo theme={{ isDarkMode }}>theGlitch</StyledLogo>
<StyledImg src={article?.img} alt={article?.alt}/>
</StyledHeroWrapper>
<StyledHeadline>{article?.header}<br/></StyledHeadline>
<StyledSubhead>{article?.subhead}</StyledSubhead>
<StyledArticleInfo>
<StyledAuthor
theme={{ isDarkMode }}
to={/profiles
}
aria-label={to profiles
}
>{article?.author}</StyledAuthor>
{formattedDate}
</StyledArticleInfo>
<StyledButtonWrapper>
<StyledShareButton onClick={copyLink} theme={{ isDarkMode }}>
<StyledShareImgIcon src={isDarkMode ? CopyLinkIconDark : CopyLinkIconLight} alt="copy link icon" />
</StyledShareButton>
<StyledShareButton theme={{ isDarkMode }}>
<a href={https://www.facebook.com/sharer/sharer.php?u=https://theglitchnews.netlify.app/article/${article?.articleUrl}"e=${article?.header} | #theGlitch
} target="_blank" rel="noopener noreferrer">
<StyledShareImgIcon src={isDarkMode ? FacebookShareIconDark : FacebookShareIconLight} alt="facebook share icon"/>
</a>
</StyledShareButton>
<StyledShareButton theme={{ isDarkMode }}>
<a href={https://twitter.com/share?text=${encodeURIComponent(article?.header + " | #theGlitch #tech")}&url=${encodeURIComponent("https://theglitchnews.netlify.app/article/" + article?.articleUrl)}
} target="_blank" rel="noopener noreferrer">
<StyledShareImgIcon src={isDarkMode ? TwitterShareIconDark : TwitterShareIconLight} />
</a>
</StyledShareButton>
</StyledButtonWrapper>
<article>
{article?.articleBody.map((paragraph, index)=><StyledArticleBody key={index}>{paragraph}</StyledArticleBody>)}
</article>
</main>
</>
)
}
export default Article ```
MetaTags.tsx: ``` import { Helmet } from 'react-helmet';
type MetaTagsProps = { title: string; description: string; imageUrl: string; url: string; }
const MetaTags = ({title, description, imageUrl, url}: MetaTagsProps) => { return ( <Helmet> <title>theGlitch</title> <meta name="description" content={description} />
{/* OpenGraph tags */}
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={https://theglitchnews.netlify.app${imageUrl}
} />
<meta property="og:url" content={url} />
{/* Twitter Card tags */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:creator" content="@EtAl19820625" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={https://theglitchnews.netlify.app/${imageUrl}
} />
<meta name="twitter:url" content={url} />
</Helmet>
);
};
export default MetaTags; ```
Editor and writer for isGlitch.com - the online-est of tech rags.