Skip to content

bug: Pinterest social share link not generated correctly. #812

Open
@sedward5

Description

@sedward5

Expected Behavior

The Pinterest social share link generated for each post should:

  1. Use the page title as the description.
  2. Use the URL of the featured_image for the media parameter.
  3. Properly encode all fields (e.g., no special characters causing issues).

Example of expected Pinterest share link:
For the site: https://sedward5.com/deltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia/

https://www.pinterest.com/pin/create/button/?url=https%3A%2F%2Fsedward5.com%2Fdeltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia%2F&media=https%3A%2F%2Fsedward5.com%2Fdeltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia%2FIMG_2678-scaled.webp&description=Delta%20Sky%20Breeze

Current Behavior

The generated Pinterest share link incorrectly:

  1. Uses the page summary as the description, which is often verbose and unsuitable.
  2. Uses the permalink URL as the media, which should be the featured image URL.
  3. This results in an error when attempting to share on Pinterest

Example of generated link:
https://pinterest.com/pin/create/button/?&description=+Jump+to+Recipe+For+a+period+of+time%2C+and+perhaps+even+still+to+a+dedicated+few%2C+a+cocktail+known+as+the+Sky+Breeze+reigned+supreme+in+the+rarefied+atmosphere+of+Delta+Airlines+flights.+This+was+not+your+average+in-flight+drink%3B+the+Sky+Breeze+was+an+esoteric+libation+with+its+own+dedicated+following%2C+a+cocktail+cult%2C+if+you+will.%0AWhile+the+Sky+Breeze+is+based+on+a+terrestrial+cocktail%2C+something+about+sipping+it+at+30%2C000+feet+made+it+extraordinary.+A+blend+of+Sky+Vodka%2C+Mott%E2%80%99s+Cranberry+Apple+Juice%2C+and+a+can+of+Fresca%2C+it+was+a+deceptively+simple+mix+that+delivered+a+sweet%2C+fruity%2C+and+refreshing+drink+%E2%80%93+a+perfect+companion+for+the+long+haul.%0A&media=https%3A%2F%2Fsedward5.com%2Fdeltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia%2F&url=https%3A%2F%2Fsedward5.com%2Fdeltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia%2F

Possible Solution

Update the getShareLink.html partial to correctly extract and encode the required fields when working with Pinterest:

  1. Use .Title for the description.
  2. Use .Params.featured_image for the media (fall back to a default if not set). Or utilize the get partial "func/GetFeaturedImage.html"
  3. Properly encode URLs and descriptions.

Proposed code update:

{{- $title := $context.Title | transform.Plainify | transform.HTMLEscape -}}
{{- $description := $context.Title | transform.Plainify | transform.HTMLEscape -}}
{{- $permalink := $context.Permalink | transform.HTMLEscape -}}
{{- $media := $context.Params.featured_image | default "default-image-url" | transform.AbsURL | transform.HTMLEscape -}}

{{- $link := fmt.Printf "%s?" $setup.link -}}
{{- $link = fmt.Printf "%surl=%s" $link $permalink -}}
{{- $link = fmt.Printf "%s&media=%s" $link $media -}}
{{- $link = fmt.Printf "%s&description=%s" $link $description -}}

{{- return $link -}}

Steps to Reproduce

  1. Use the Pinterest share button on a post with a featured image and summary.
  2. Inspect the generated Pinterest URL.
  3. Note the issues with the description and media parameters.
  4. Attempt to share a post on Pinterest

The bigger picture (we need context)

  • Running MacOS 15.2

  • Also Running in CloudFlare pages.

  • hugo v0.139.3+extended+withdeploy darwin/amd64 BuildDate=2024-11-29T15:36:56Z VendorInfo=brew

  • go version go1.23.4 darwin/amd64

  • b06949e themes/gohugo-theme-ananke (v2.11.2-17-gb06949e)

Hugo Config

archetypedir = 'archetypes'
assetdir = 'assets'
baseurl = 'https://sedward5.com/'
cachedir = 'xxxxx/Library/Caches/hugo_cache'
canonifyurls = true
capitalizelisttitles = true
contentdir = 'content'
datadir = 'data'
defaultcontentlanguage = 'en'
enablerobotstxt = true
environment = 'production'
i18ndir = 'i18n'
layoutdir = 'layouts'
pluralizelisttitles = true
publishdir = 'public'
resourcedir = 'resources'
staticdir = ['static']
summarylength = 70
theme = ['gohugo-theme-ananke']
themesdir = 'themes'
timeout = '30s'
title = 'Cyber Mixology'
titlecasestyle = 'AP'
workingdir = 'xxxxx/hugo-sedward5.com'

[build]
useresourcecachewhen = 'fallback'

[build.buildstats]

[[build.cachebusters]]
source = '(postcss|tailwind).config.js'
target = '(css|styles|scss|sass)'

[caches]
[caches.assets]
dir = ':resourceDir/_gen'
maxage = -1

[caches.getcsv]
dir = ':cacheDir/:project'
maxage = -1

[caches.getjson]
dir = ':cacheDir/:project'
maxage = -1

[caches.getresource]
dir = ':cacheDir/:project'
maxage = -1

[caches.images]
dir = ':resourceDir/_gen'
maxage = -1

[caches.misc]
dir = ':cacheDir/:project'
maxage = -1

[caches.modules]
dir = ':cacheDir/modules'
maxage = -1

[deployment]
invalidatecdn = true
maxdeletes = 256
workers = 10

[frontmatter]
date = ['date', 'publishdate', 'pubdate', 'published', 'lastmod', 'modified']
expirydate = ['expirydate', 'unpublishdate']
lastmod = [':git', 'lastmod', 'modified', 'date', 'publishdate', 'pubdate', 'published']
publishdate = ['publishdate', 'pubdate', 'published', 'date']

[httpcache]
[httpcache.cache]
[httpcache.cache.for]
excludes = ['**']

[[httpcache.polls]]
disable = true
high = '0s'
low = '0s'

[httpcache.polls.for]
  includes = ['**']

[imaging]
bgcolor = '#ffffff'
hint = 'photo'
quality = 75
resamplefilter = 'box'

[languages]
[languages.en]

[markup]
defaultmarkdownhandler = 'goldmark'

[markup.asciidocext]
backend = 'html5'
failurelevel = 'fatal'
noheaderorfooter = true
safemode = 'unsafe'

[markup.goldmark]
[markup.goldmark.extensions]
definitionlist = true
footnote = true
linkify = true
linkifyprotocol = 'https'
strikethrough = true
table = true
tasklist = true

  [markup.goldmark.extensions.cjk]
    eastasianlinebreaksstyle = 'simple'

  [markup.goldmark.extensions.extras]
    [markup.goldmark.extensions.extras.delete]

    [markup.goldmark.extensions.extras.insert]

    [markup.goldmark.extensions.extras.mark]

    [markup.goldmark.extensions.extras.subscript]

    [markup.goldmark.extensions.extras.superscript]

  [markup.goldmark.extensions.passthrough]
    [markup.goldmark.extensions.passthrough.delimiters]

  [markup.goldmark.extensions.typographer]
    apostrophe = '’'
    ellipsis = '…'
    emdash = '—'
    endash = '–'
    leftanglequote = '«'
    leftdoublequote = '“'
    leftsinglequote = '‘'
    rightanglequote = '»'
    rightdoublequote = '”'
    rightsinglequote = '’'

[markup.goldmark.parser]
  autoheadingid = true
  autoheadingidtype = 'github'
  wrapstandaloneimagewithinparagraph = true

  [markup.goldmark.parser.attribute]
    title = true

[markup.goldmark.renderer]
  unsafe = true

[markup.goldmark.renderhooks]
  [markup.goldmark.renderhooks.image]

  [markup.goldmark.renderhooks.link]

[markup.highlight]
codefences = true
linenostart = 1
linenumbersintable = true
noclasses = true
style = 'monokai'
tabwidth = 4

[markup.tableofcontents]
endlevel = 3
startlevel = 2

[mediatypes]
[mediatypes.'application/json']
delimiter = '.'
suffixes = ['json']

[mediatypes.'application/manifest+json']
delimiter = '.'
suffixes = ['webmanifest']

[mediatypes.'application/octet-stream']
delimiter = '.'

[mediatypes.'application/pdf']
delimiter = '.'
suffixes = ['pdf']

[mediatypes.'application/rss+xml']
delimiter = '.'
suffixes = ['xml', 'rss']

[mediatypes.'application/toml']
delimiter = '.'
suffixes = ['toml']

[mediatypes.'application/wasm']
delimiter = '.'
suffixes = ['wasm']

[mediatypes.'application/xml']
delimiter = '.'
suffixes = ['xml']

[mediatypes.'application/yaml']
delimiter = '.'
suffixes = ['yaml', 'yml']

[mediatypes.'font/otf']
delimiter = '.'
suffixes = ['otf']

[mediatypes.'font/ttf']
delimiter = '.'
suffixes = ['ttf']

[mediatypes.'image/bmp']
delimiter = '.'
suffixes = ['bmp']

[mediatypes.'image/gif']
delimiter = '.'
suffixes = ['gif']

[mediatypes.'image/jpeg']
delimiter = '.'
suffixes = ['jpg', 'jpeg', 'jpe', 'jif', 'jfif']

[mediatypes.'image/png']
delimiter = '.'
suffixes = ['png']

[mediatypes.'image/svg+xml']
delimiter = '.'
suffixes = ['svg']

[mediatypes.'image/tiff']
delimiter = '.'
suffixes = ['tif', 'tiff']

[mediatypes.'image/webp']
delimiter = '.'
suffixes = ['webp']

[mediatypes.'text/asciidoc']
delimiter = '.'
suffixes = ['adoc', 'asciidoc', 'ad']

[mediatypes.'text/calendar']
delimiter = '.'
suffixes = ['ics']

[mediatypes.'text/css']
delimiter = '.'
suffixes = ['css']

[mediatypes.'text/csv']
delimiter = '.'
suffixes = ['csv']

[mediatypes.'text/html']
delimiter = '.'
suffixes = ['html', 'htm']

[mediatypes.'text/javascript']
delimiter = '.'
suffixes = ['js', 'jsm', 'mjs']

[mediatypes.'text/jsx']
delimiter = '.'
suffixes = ['jsx']

[mediatypes.'text/markdown']
delimiter = '.'
suffixes = ['md', 'mdown', 'markdown']

[mediatypes.'text/org']
delimiter = '.'
suffixes = ['org']

[mediatypes.'text/pandoc']
delimiter = '.'
suffixes = ['pandoc', 'pdc']

[mediatypes.'text/plain']
delimiter = '.'
suffixes = ['txt']

[mediatypes.'text/rst']
delimiter = '.'
suffixes = ['rst']

[mediatypes.'text/tsx']
delimiter = '.'
suffixes = ['tsx']

[mediatypes.'text/typescript']
delimiter = '.'
suffixes = ['ts']

[mediatypes.'text/x-sass']
delimiter = '.'
suffixes = ['sass']

[mediatypes.'text/x-scss']
delimiter = '.'
suffixes = ['scss']

[mediatypes.'video/3gpp']
delimiter = '.'
suffixes = ['3gpp', '3gp']

[mediatypes.'video/mp4']
delimiter = '.'
suffixes = ['mp4']

[mediatypes.'video/mpeg']
delimiter = '.'
suffixes = ['mpg', 'mpeg']

[mediatypes.'video/ogg']
delimiter = '.'
suffixes = ['ogv']

[mediatypes.'video/webm']
delimiter = '.'
suffixes = ['webm']

[mediatypes.'video/x-msvideo']
delimiter = '.'
suffixes = ['avi']

[menus]
[[menus.main]]
name = 'Home'
pageref = '/'
weight = 10

[[menus.main]]
name = 'Cocktails'
pageref = '/categories/cocktails'
weight = 20

[[menus.main]]
name = 'Security'
pageref = '/categories/security'
weight = 30

[[menus.main]]
name = 'About'
pageref = '/about'
weight = 40

[minify]
[minify.tdewolff]
[minify.tdewolff.css]
keepcss2 = true

[minify.tdewolff.html]
  keepdefaultattrvals = true
  keepdocumenttags = true
  keependtags = true
  keepspecialcomments = true
  templatedelims = ['', '']

[minify.tdewolff.js]
  version = 2022

[minify.tdewolff.json]

[minify.tdewolff.svg]

[minify.tdewolff.xml]

[module]
noproxy = 'none'
private = '.'
proxy = 'direct'
workspace = 'off'

[module.hugoversion]

[[module.imports]]
path = 'gohugo-theme-ananke'

[[module.mounts]]
source = 'content'
target = 'content'

[[module.mounts]]
source = 'data'
target = 'data'

[[module.mounts]]
source = 'layouts'
target = 'layouts'

[[module.mounts]]
source = 'i18n'
target = 'i18n'

[[module.mounts]]
source = 'archetypes'
target = 'archetypes'

[[module.mounts]]
source = 'assets'
target = 'assets'

[[module.mounts]]
source = 'static'
target = 'static'

[outputformats]
[outputformats.amp]
basename = 'index'
ishtml = true
mediatype = 'text/html'
path = 'amp'
permalinkable = true
rel = 'amphtml'

[outputformats.calendar]
basename = 'index'
isplaintext = true
mediatype = 'text/calendar'
protocol = 'webcal://'
rel = 'alternate'

[outputformats.css]
basename = 'styles'
isplaintext = true
mediatype = 'text/css'
notalternative = true
rel = 'stylesheet'

[outputformats.csv]
basename = 'index'
isplaintext = true
mediatype = 'text/csv'
rel = 'alternate'

[outputformats.html]
basename = 'index'
ishtml = true
mediatype = 'text/html'
permalinkable = true
rel = 'canonical'
weight = 10

[outputformats.json]
basename = 'cocktail-index'
isplaintext = true
mediatype = 'application/json'
rel = 'alternate'

[outputformats.markdown]
basename = 'index'
isplaintext = true
mediatype = 'text/markdown'
rel = 'alternate'

[outputformats.robots]
basename = 'robots'
isplaintext = true
mediatype = 'text/plain'
rel = 'alternate'
root = true

[outputformats.rss]
basename = 'index'
mediatype = 'application/rss+xml'
nougly = true
rel = 'alternate'

[outputformats.sitemap]
basename = 'sitemap'
mediatype = 'application/xml'
rel = 'sitemap'
ugly = true

[outputformats.webappmanifest]
basename = 'manifest'
isplaintext = true
mediatype = 'application/manifest+json'
notalternative = true
rel = 'manifest'

[outputs]
home = ['html', 'json']
page = ['html']
rss = ['rss']
section = ['html', 'rss']
taxonomy = ['html', 'rss']
term = ['html', 'rss']

[page]
nextprevinsectionsortorder = 'desc'
nextprevsortorder = 'desc'

[pagination]
pagersize = 10
path = 'page'

[params]
author = 'Steve Edwards'
custom_css = ['css/custom.css', 'css/print-recipe.css']
custom_js = ['js/print_recipe.js']
site_logo = 'logo.svg'
subtitle = 'sedward5.com'

[params.ananke]
show_recent_posts = true

[params.ananke.social]
  icon_path = 'ananke/socials/%s.svg'

  [params.ananke.social.bluesky]
    username = 'sedward5'

  [params.ananke.social.facebook]
    username = 'cyber-mixology'

  [params.ananke.social.follow]
    networks = ['facebook', 'bluesky', 'linkedin', 'github']

  [params.ananke.social.github]
    username = 'sedward5'

  [params.ananke.social.linkedin]
    username = 'sedward5'

  [[params.ananke.social.networks]]
    color = '#1185fe'
    icon = 'bluesky'
    label = 'Bluesky'
    link = 'https://bsky.app/intent/compose'
    profile = 'https://bsky.app/profile/%s'
    slug = 'bluesky'

    [params.ananke.social.networks.particles]
      text = 'permalink'

  [[params.ananke.social.networks]]
    icon = 'envelope'
    label = 'Email'
    link = 'mailto:'
    slug = 'email'

    [params.ananke.social.networks.particles]
      body = 'permalink'
      subject = 'title'

  [[params.ananke.social.networks]]
    color = '#3b5998'
    icon = 'facebook'
    label = 'Facebook'
    link = 'https://facebook.com/sharer/sharer.php'
    profile = 'https://www.facebook.com/%s'
    slug = 'facebook'

    [params.ananke.social.networks.particles]
      u = 'permalink'

  [[params.ananke.social.networks]]
    color = '#6cc644'
    icon = 'github'
    label = 'GitHub'
    profile = 'https://github.com/%s/'
    slug = 'github'

  [[params.ananke.social.networks]]
    color = '#FC6D26'
    icon = 'gitlab'
    label = 'GitLab'
    profile = 'https://gitlab.com/%s/'
    slug = 'gitlab'

  [[params.ananke.social.networks]]
    color = '#ff4000'
    icon = 'hacker-news'
    label = 'Hacker News'
    link = 'https://news.ycombinator.com/submitlink'
    profile = 'https://news.ycombinator.com/user?id=%s'
    slug = 'hackernews'

    [params.ananke.social.networks.particles]
      t = 'description'
      u = 'permalink'

  [[params.ananke.social.networks]]
    color = '#e1306c'
    icon = 'instagram'
    label = 'Instagram'
    profile = 'https://www.instagram.com/%s/'
    slug = 'instagram'

  [[params.ananke.social.networks]]
    color = '#3d76ff'
    icon = 'keybase'
    label = 'Keybase'
    profile = 'https://keybase.io/%s'
    slug = 'keybase'

  [[params.ananke.social.networks]]
    color = '#0077b5'
    icon = 'linkedin'
    label = 'LinkedIn'
    link = 'https://www.linkedin.com/shareArticle'
    profile = 'http://linkedin.com/in/%s'
    slug = 'linkedin'

    [params.ananke.social.networks.particles]
      params = 'mini=true'
      source = 'permalink'
      summary = 'description'
      title = 'title'
      url = 'permalink'

  [[params.ananke.social.networks]]
    color = '#0077b5'
    icon = 'medium'
    label = 'Medium'
    profile = 'https://medium.com/@%s/'
    slug = 'medium'

  [[params.ananke.social.networks]]
    color = '#6364FF'
    icon = 'mastodon'
    label = 'Mastodon'
    slug = 'mastodon'

  [[params.ananke.social.networks]]
    color = '#e60023'
    icon = 'pinterest'
    label = 'Pinterest'
    link = 'https://pinterest.com/pin/create/button/'
    profile = 'https://www.pinterest.com/%s/'
    slug = 'pinterest'

    [params.ananke.social.networks.particles]
      description = 'description'
      media = 'permalink'
      url = 'permalink'

  [[params.ananke.social.networks]]
    color = '#ff4500'
    icon = 'reddit'
    label = 'Reddit'
    link = 'https://reddit.com/submit/'
    profile = 'https://www.reddit.com/user/%s/'
    slug = 'reddit'

    [params.ananke.social.networks.particles]
      params = 'resubmit=true'
      title = 'title'
      url = 'permalink'

  [[params.ananke.social.networks]]
    color = '#ff6f1a'
    icon = 'rss'
    label = 'RSS'
    slug = 'rss'

  [[params.ananke.social.networks]]
    color = '#E01E5A'
    icon = 'slack'
    label = 'Slack'
    slug = 'slack'

  [[params.ananke.social.networks]]
    color = '#f48024'
    icon = 'stack-overflow'
    label = 'Stack Overflow'
    profile = 'https://stackoverflow.com/users/%s'
    slug = 'stackoverflow'

  [[params.ananke.social.networks]]
    color = '#0088cc'
    icon = 'telegram'
    label = 'Telegram'
    link = 'https://telegram.me/share/url'
    profile = 'https://t.me/%s'
    slug = 'telegram'

    [params.ananke.social.networks.particles]
      text = 'description'
      url = 'permalink'

  [[params.ananke.social.networks]]
    color = '#fe2c55'
    icon = 'tiktok'
    label = 'TikTok'
    profile = 'https://www.tiktok.com/@%s'
    slug = 'tiktok'

  [[params.ananke.social.networks]]
    color = '#35465c'
    icon = 'tumblr'
    label = 'Tumblr'
    link = 'https://www.tumblr.com/widgets/share/tool'
    profile = 'https://www.tumblr.com/blog/%s'
    slug = 'tumblr'

    [params.ananke.social.networks.particles]
      canonicalurl = 'permalink'
      caption = 'description'
      content = 'description'
      params = 'posttype=link'
      sharesource = 'source'
      title = 'title'

  [[params.ananke.social.networks]]
    color = '#1da1f2'
    icon = 'twitter'
    label = 'Twitter'
    link = 'https://twitter.com/intent/tweet/'
    profile = 'https://twitter.com/%s'
    slug = 'twitter'

    [params.ananke.social.networks.particles]
      text = 'description'
      url = 'permalink'

  [[params.ananke.social.networks]]
    color = '#25d366'
    icon = 'whatsapp'
    label = 'WhatsApp'
    link = 'whatsapp://send'
    linkintext = true
    slug = 'whatsapp'

    [params.ananke.social.networks.particles]
      text = 'description'

  [[params.ananke.social.networks]]
    color = '#026466'
    icon = 'xing'
    label = 'Xing'
    link = 'https://www.xing.com/app/user'
    profile = 'https://www.xing.com/profile/%s'
    separator = ';'
    slug = 'xing'

    [params.ananke.social.networks.particles]
      params = 'op=share'
      title = 'title'
      url = 'permalink'

  [[params.ananke.social.networks]]
    color = '#000000'
    icon = 'x-twitter'
    label = 'X'
    link = 'https://twitter.com/intent/tweet/'
    profile = 'https://x.com/%s'
    slug = 'x-twitter'

    [params.ananke.social.networks.particles]
      text = 'description'
      url = 'permalink'

  [[params.ananke.social.networks]]
    color = '#cd201f'
    icon = 'youtube'
    label = 'YouTube'
    profile = 'https://www.youtube.com/@%s'
    slug = 'youtube'

  [params.ananke.social.share]
    icons = true
    networks = ['email', 'facebook', 'bluesky', 'linkedin']
    sharetext = true

[permalinks]

[privacy]
[privacy.disqus]

[privacy.googleanalytics]

[privacy.instagram]

[privacy.twitter]

[privacy.vimeo]

[privacy.youtube]

[related]
threshold = 80

[[related.indices]]
name = 'keywords'
type = 'basic'
weight = 100

[[related.indices]]
name = 'date'
type = 'basic'
weight = 10

[[related.indices]]
name = 'tags'
type = 'basic'
weight = 80

[security]
[security.exec]
allow = ['^(dart-)?sass(-embedded)?$', '^go$', '^git$', '^npx$', '^postcss$', '^tailwindcss$']
osenv = ['(?i)^((HTTPS?|NO)PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+|(XDG_CONFIG)?HOME|USERPROFILE|SSH_AUTH_SOCK|DISPLAY|LANG|SYSTEMDRIVE)$']

[security.funcs]
getenv = ['^HUGO_', '^CI$']

[security.http]
methods = ['(?i)GET|POST']
urls = ['.*']

[server]
[[server.redirects]]
from = '**'
status = 404
to = '/404.html'

[services]
[services.disqus]

[services.googleanalytics]
id = 'xxxxx'

[services.instagram]

[services.rss]
limit = -1

[services.twitter]

[sitemap]
filename = 'sitemap.xml'
priority = -1

[taxonomies]
category = 'categories'
tag = 'tags'

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions