Skip to content

Commit

Permalink
Add functions for setting description and OG meta
Browse files Browse the repository at this point in the history
It's common that a website author will want to add a specific
description and Open Graph image to a given page in their website. These
functions are simple conveniences to add these meta tags to the document
head.

I decided against simply adding all possible meta tags, because not all
of them are useful, and even in the case of Open Graph tags, many of
them should be set only once and they should use the same value for the
entire website. In those cases, it's probably better for the website
author to add those tags in their layout template.

Closes #1659
  • Loading branch information
jezen committed Mar 30, 2020
1 parent 4a4dd06 commit a3c2061
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 4 deletions.
4 changes: 4 additions & 0 deletions yesod-core/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# ChangeLog for yesod-core

## 1.6.18

* Add functions for setting description and OG meta

## 1.6.17.3

* Support for `unliftio-core` 0.2
Expand Down
77 changes: 73 additions & 4 deletions yesod-core/src/Yesod/Core/Widget.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ module Yesod.Core.Widget
-- ** Head of page
, setTitle
, setTitleI
, setDescription
, setDescriptionI
, setOGType
, setOGImage
-- ** CSS
, addStylesheet
, addStylesheetAttrs
Expand Down Expand Up @@ -160,18 +164,83 @@ instance ToWidgetHead site Javascript where
instance ToWidgetHead site Html where
toWidgetHead = toWidgetHead . const

-- | Set the page title. Calling 'setTitle' multiple times overrides previously
-- set values.
-- | Set the page title.
--
-- Calling @setTitle@ or @setTitleI@ multiple times overrides previously set
-- values.
--
-- SEO Notes:
--
-- * Title tags are the second most important on-page factor for SEO, after
-- content
-- * Every page should have a unique title tag
-- * Start your title tag with your main targeted keyword
-- * Don't stuff your keywords
-- * Google typically shows 55-64 characters, so aim to keep your title
-- length under 60 characters
setTitle :: MonadWidget m => Html -> m ()
setTitle x = tell $ GWData mempty (Last $ Just $ Title x) mempty mempty mempty mempty mempty

-- | Set the page title. Calling 'setTitle' multiple times overrides previously
-- set values.
-- | Set the localised page title.
--
-- n.b. See comments for @setTitle@
setTitleI :: (MonadWidget m, RenderMessage (HandlerSite m) msg) => msg -> m ()
setTitleI msg = do
mr <- getMessageRender
setTitle $ toHtml $ mr msg

-- | Add description meta tag to the head of the page
--
-- Google does not use the description tag as a ranking signal, but the
-- contents of this tag will likely affect your click-through rate since it
-- shows up in search results.
--
-- The average length of the description shown in Google's search results is
-- about 160 characters on desktop, and about 130 characters on mobile, at time
-- of writing.
--
-- Source: https://www.advancedwebranking.com/blog/meta-tags-important-in-seo/
--
-- @since 1.6.18
setDescription :: MonadWidget m => Text -> m ()
setDescription description =
toWidgetHead $ [hamlet|<meta name=description content=#{description}>|]

-- | Add translated description meta tag to the head of the page
--
-- n.b. See comments for @setDescription@.
--
-- @since 1.6.18
setDescriptionI
:: (MonadWidget m, RenderMessage (HandlerSite m) msg)
=> msg -> m ()
setDescriptionI msg = do
mr <- getMessageRender
toWidgetHead $ [hamlet|<meta name=description content=#{mr msg}>|]

-- | Add OpenGraph type meta tag to the head of the page
--
-- See all available OG types here: https://ogp.me/#types
--
-- @since 1.6.18
setOGType :: MonadWidget m => Text -> m ()
setOGType a = toWidgetHead $ [hamlet|<meta name="og:type" content=#{a}>|]

-- | Add OpenGraph image meta tag to the head of the page
--
-- Best practices:
--
-- * Use custom images for shareable pages, e.g., homepage, articles, etc.
-- * Use your logo or any other branded image for the rest of your pages.
-- * Use images with a 1.91:1 ratio and minimum recommended dimensions of
-- 1200x630 for optimal clarity across all devices.
--
-- Source: https://ahrefs.com/blog/open-graph-meta-tags/
--
-- @since 1.6.18
setOGImage :: MonadWidget m => Text -> m ()
setOGImage a = toWidgetHead $ [hamlet|<meta name="og:image" content=#{a}>|]

-- | Link to the specified local stylesheet.
addStylesheet :: MonadWidget m => Route (HandlerSite m) -> m ()
addStylesheet = flip addStylesheetAttrs []
Expand Down

0 comments on commit a3c2061

Please sign in to comment.