Skip Navigation
Lemmy Support @lemmy.ml EtAl @lemmy.dbzer0.com

How to optimize images for Lemmy thumbnails?

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}&quote=${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;
5

You're viewing a single thread.

5 comments
  • Post the resulting html code. Basically whatever you get when you run curl on a URL is what Lemmy sees as well. The React code is more or less irrelevant.

    • <!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?

      • You basically have to do on the server side what React is doing on the client side. Maybe nodejs can do that. I don't know, I'm not too familiar with either.

    • <!DOCTYPE html>
      <html lang="en" style="--background-color: #131313;">
      <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&amp;family=Open+Sans:ital,wght@0,300;1,300&amp;family=Quattrocento&amp;family=Source+Serif+4:ital,opsz@0,8..60;1,8..60&amp;display=swap" rel="stylesheet">
          <script type="module" crossorigin="" src="/assets/index-K-gY7Fqn.js"></script>
          <link rel="stylesheet" crossorigin="" href="/assets/index-0ZvQpehw.css">
          <style data-styled="active" data-styled-version="6.1.8"></style>
          <meta property="og:url" content="https://theglitchnews.netlify.app/article/20240604-invasion-of-the" data-react-helmet="true">
          <meta name="twitter:card" content="summary_large_image" data-react-helmet="true">
          <meta name="twitter:creator" content="@EtAl19820625" data-react-helmet="true">
          <meta name="twitter:url" content="https://theglitchnews.netlify.app/article/20240604-invasion-of-the" data-react-helmet="true">
          <meta name="description" content="Silicon Valley Meets the Uncanny Valley in Doppelgänger Mystery" data-react-helmet="true">
          <meta property="og:title" content="Invasion of the Body Zoomers" data-react-helmet="true">
          <meta property="og:description" content="Silicon Valley Meets the Uncanny Valley in Doppelgänger Mystery" data-react-helmet="true">
          <meta property="og:image" content="https://theglitchnews.netlify.app/images/20240604-invasion-of-the.png" data-react-helmet="true">
          <meta name="twitter:title" content="Invasion of the Body Zoomers" data-react-helmet="true">
          <meta name="twitter:description" content="Silicon Valley Meets the Uncanny Valley in Doppelgänger Mystery" data-react-helmet="true">
          <meta name="twitter:image" content="https://theglitchnews.netlify.app//images/20240604-invasion-of-the.png" data-react-helmet="true">
      </head>
      <body>
          <div id="root"><div class="dark"><div class="main-wrapper"><header class="sc-fsYfdN UHjJG"><h2 class="sc-qZrbh ghikee">Article</h2><nav><ul class="sc-jsEeTM hEfcP"><li class="sc-kFCroH eIgcmz"><button class="sc-irLvIq iIloDy">Menu<img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20448%20512'%3e%3c!--!Font%20Awesome%20Free%206.5.2%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license/free%20Copyright%202024%20Fonticons,%20Inc.--%3e%3cpath%20fill='%23ffffff'%20d='M256%2080c0-17.7-14.3-32-32-32s-32%2014.3-32%2032V224H48c-17.7%200-32%2014.3-32%2032s14.3%2032%2032%2032H192V432c0%2017.7%2014.3%2032%2032%2032s32-14.3%2032-32V288H400c17.7%200%2032-14.3%2032-32s-14.3-32-32-32H256V80z'/%3e%3c/svg%3e" alt="menu icon" class="sc-csKJxZ mlmDK"></button></li></ul></nav><button class="sc-eTNRI jAwVxu"><img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20512%20512'%3e%3c!--!Font%20Awesome%20Free%206.5.2%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license/free%20Copyright%202024%20Fonticons,%20Inc.--%3e%3cpath%20fill='%23000000'%20d='M233.4%20105.4c12.5-12.5%2032.8-12.5%2045.3%200l192%20192c12.5%2012.5%2012.5%2032.8%200%2045.3s-32.8%2012.5-45.3%200L256%20173.3%2086.6%20342.6c-12.5%2012.5-32.8%2012.5-45.3%200s-12.5-32.8%200-45.3l192-192z'/%3e%3c/svg%3e" class="sc-brSamD fGFWBJ"></button><div class="sc-dmyCSP fiXDCU" style="position: fixed; top: 0px; right: -16px; width: 21.5rem; height: 100vh; background-color: rgb(82, 0, 255); padding: 1.25rem; transform: translateX(23rem); transition: transform 0.1s ease-out 0s;"><div class="sc-hLQSwg hlKNoQ"><div class="sc-beySPh birwGZ"><div class="sc-guDLey jqFeEG"></div></div><button class="sc-eDLKkx fvLRvy"><img src="data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20width='500'%20height='500'%20viewBox='0%200%20500%20500'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20fill='%2392D10E'%20stroke='%2392D10E'%20stroke-width='100'%3e%3cpath%20d='M50,50%20L450,450'%20/%3e%3cpath%20d='M50,450%20L450,50'%20/%3e%3c/g%3e%3c/svg%3e" alt="sidebar close button icon" class="sc-jTQCzO hfKhPP"></button></div><ul class="sc-gLLuof kQKVdU"><li><a aria-label="to home page" class="sc-iBdnpw kldMOa" href="/" style="">Home</a></li><li><a aria-label="to tech page" class="sc-iBdnpw kldMOa" href="/tech">Tech</a></li><li><a aria-label="to reviews page" class="sc-iBdnpw kldMOa" href="/reviews">Reviews</a></li><li><a aria-label="to entertainment page" class="sc-iBdnpw kldMOa" href="/entertainment">Entertainment</a></li><li><a aria-label="to ai page" class="sc-iBdnpw kldMOa" href="/ai">AI</a></li><li><a aria-label="to contact us page" class="sc-iBdnpw kldMOa" href="/contact">Contact Us</a></li></ul></div></header><main><div class="sc-ktwOfi VeazV"><h2 class="sc-hABBmJ hAqoSv">theGlitch</h2><img class="sc-fmKFGs jJHeyq" src="/images/20240604-invasion-of-the.png" alt="three identical blonde women sitting at a table"></div><h1 class="sc-fHejqy iIwpNo">Invasion of the Body Zoomers<br></h1><h3 class="sc-blmEgr eGENWr">Silicon Valley Meets the Uncanny Valley in Doppelgänger Mystery</h3><p class="sc-ifyrAs gKSiUB"><a aria-label="to profiles" class="sc-dJGMql iQfyVB" href="/profiles">Et Al</a>June 4, 2024</p><div class="sc-hIPBNq esTubt"><button class="sc-dmXWDj CPnhW"><img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20640%20512'%3e%3c!--!Font%20Awesome%20Free%206.5.2%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license/free%20Copyright%202024%20Fonticons,%20Inc.--%3e%3cpath%20fill='%23ffffff'%20d='M579.8%20267.7c56.5-56.5%2056.5-148%200-204.5c-50-50-128.8-56.5-186.3-15.4l-1.6%201.1c-14.4%2010.3-17.7%2030.3-7.4%2044.6s30.3%2017.7%2044.6%207.4l1.6-1.1c32.1-22.9%2076-19.3%20103.8%208.6c31.5%2031.5%2031.5%2082.5%200%20114L422.3%20334.8c-31.5%2031.5-82.5%2031.5-114%200c-27.9-27.9-31.5-71.8-8.6-103.8l1.1-1.6c10.3-14.4%206.9-34.4-7.4-44.6s-34.4-6.9-44.6%207.4l-1.1%201.6C206.5%20251.2%20213%20330%20263%20380c56.5%2056.5%20148%2056.5%20204.5%200L579.8%20267.7zM60.2%20244.3c-56.5%2056.5-56.5%20148%200%20204.5c50%2050%20128.8%2056.5%20186.3%2015.4l1.6-1.1c14.4-10.3%2017.7-30.3%207.4-44.6s-30.3-17.7-44.6-7.4l-1.6%201.1c-32.1%2022.9-76%2019.3-103.8-8.6C74%20372%2074%20321%20105.5%20289.5L217.7%20177.2c31.5-31.5%2082.5-31.5%20114%200c27.9%2027.9%2031.5%2071.8%208.6%20103.9l-1.1%201.6c-10.3%2014.4-6.9%2034.4%207.4%2044.6s34.4%206.9%2044.6-7.4l1.1-1.6C433.5%20260.8%20427%20182%20377%20132c-56.5-56.5-148-56.5-204.5%200L60.2%20244.3z'/%3e%3c/svg%3e" alt="copy link icon" class="sc-khjJXk lmmBHa"></button><button class="sc-dmXWDj CPnhW"><a href="https://www.facebook.com/sharer/sharer.php?u=https://theglitchnews.netlify.app/article/20240604-invasion-of-the&amp;quote=Invasion of the Body Zoomers | #theGlitch" target="_blank" rel="noopener noreferrer"><img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20512%20512'%3e%3c!--!Font%20Awesome%20Free%206.5.2%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license/free%20Copyright%202024%20Fonticons,%20Inc.--%3e%3cpath%20fill='%23ffffff'%20d='M512%20256C512%20114.6%20397.4%200%20256%200S0%20114.6%200%20256C0%20376%2082.7%20476.8%20194.2%20504.5V334.2H141.4V256h52.8V222.3c0-87.1%2039.4-127.5%20125-127.5c16.2%200%2044.2%203.2%2055.7%206.4V172c-6-.6-16.5-1-29.6-1c-42%200-58.2%2015.9-58.2%2057.2V256h83.6l-14.4%2078.2H287V510.1C413.8%20494.8%20512%20386.9%20512%20256h0z'/%3e%3c/svg%3e" alt="facebook share icon" class="sc-khjJXk lmmBHa"></a></button><button class="sc-dmXWDj CPnhW"><a href="https://twitter.com/share?text=Invasion%20of%20the%20Body%20Zoomers%20%7C%20%23theGlitch%20%23tech&amp;url=https%3A%2F%2Ftheglitchnews.netlify.app%2Farticle%2F20240604-invasion-of-the" target="_blank" rel="noopener noreferrer"><img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20512%20512'%3e%3c!--!Font%20Awesome%20Free%206.5.2%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license/free%20Copyright%202024%20Fonticons,%20Inc.--%3e%3cpath%20fill='%23ffffff'%20d='M459.4%20151.7c.3%204.5%20.3%209.1%20.3%2013.6%200%20138.7-105.6%20298.6-298.6%20298.6-59.5%200-114.7-17.2-161.1-47.1%208.4%201%2016.6%201.3%2025.3%201.3%2049.1%200%2094.2-16.6%20130.3-44.8-46.1-1-84.8-31.2-98.1-72.8%206.5%201%2013%201.6%2019.8%201.6%209.4%200%2018.8-1.3%2027.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14%207.8%2030.2%2012.7%2047.4%2013.3-28.3-18.8-46.8-51-46.8-87.4%200-19.5%205.2-37.4%2014.3-53%2051.7%2063.7%20129.3%20105.3%20216.4%20109.8-1.6-7.8-2.6-15.9-2.6-24%200-57.8%2046.8-104.9%20104.9-104.9%2030.2%200%2057.5%2012.7%2076.7%2033.1%2023.7-4.5%2046.5-13.3%2066.6-25.3-7.8%2024.4-24.4%2044.8-46.1%2057.8%2021.1-2.3%2041.6-8.1%2060.4-16.2-14.3%2020.8-32.2%2039.3-52.6%2054.3z'/%3e%3c/svg%3e" class="sc-khjJXk lmmBHa"></a></button></div><article><p class="sc-fLseNd eVALWO">Zoom's work-from-home employees got the shock of their lives recently when they discovered doppelgängers had been attending meetings in their place - face-to-face gatherings the real remote workers didn't even know existed until after the fact.</p><p class="sc-fLseNd eVALWO">"I was just catching up on my recording of the quarterly budget review," said one pajama-clad programmer. "But the weirder thing was, I somehow already had notes from it! Pages covered in my handwriting, despite me sleeping through the whole damn thing."</p><p class="sc-fLseNd eVALWO">It soon became clear that a sinister force was at play. While Zoom's homebound staff went about their daily routines, oblivious, ghostly replicas infiltrate
      </html>