Skip to content

Commit

Permalink
Add dynamic social share image (#63)
Browse files Browse the repository at this point in the history
* Add social.njk base

* Add support for social.scss and update CSS rendering

* Refactor styles and remove unused code

* Refactor social card styles and add social card component

* Update social card styles and remove social.njk file

* Refactor meta tags and add open graph screenshot URL shortcode

* Add disallow rule for /social-card/* in robots.txt

* Update meta tags for social media sharing

* Remove unnecessary code and exclude pages from collections
  • Loading branch information
afnizarnur committed Apr 26, 2024
1 parent 6c59e7f commit 3284c3e
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 83 deletions.
126 changes: 63 additions & 63 deletions src/assets/styles/__styles.11ty.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,52 +11,52 @@ const cssesc = require("cssesc")
const isProd = process.env.ELEVENTY_ENV === "production"

module.exports = class {
async data() {
const entryPath = path.join(__dirname, `/${ENTRY_FILE_NAME}`)
return {
permalink: `/assets/styles/main.css`,
eleventyExcludeFromCollections: true,
entryPath
}
}
async data() {
const entryPath = path.join(__dirname, `/${ENTRY_FILE_NAME}`)
return {
permalink: `/assets/styles/main.css`,
eleventyExcludeFromCollections: true,
entryPath
}
}

// Compile Sass to CSS,
// Embed Source Map in Development
async compile(config) {
return new Promise((resolve, reject) => {
if (!isProd) {
config.sourceMap = true
config.sourceMapEmbed = true
config.outputStyle = "compressed"
}
return sass.render(config, (err, result) => {
if (err) {
return reject(err)
}
resolve(result.css.toString())
})
})
}
// Compile Sass to CSS,
// Embed Source Map in Development
async compile(config) {
return new Promise((resolve, reject) => {
if (!isProd) {
config.sourceMap = true
config.sourceMapEmbed = true
config.outputStyle = "compressed"
}
return sass.render(config, (err, result) => {
if (err) {
return reject(err)
}
resolve(result.css.toString())
})
})
}

// Minify & Optimize with CleanCSS in Production
async minify(css) {
return new Promise((resolve, reject) => {
if (!isProd) {
resolve(css)
}
const minified = new CleanCSS().minify(css)
if (!minified.styles) {
return reject(minified.error)
}
resolve(minified.styles)
})
}
// Minify & Optimize with CleanCSS in Production
async minify(css) {
return new Promise((resolve, reject) => {
if (!isProd) {
resolve(css)
}
const minified = new CleanCSS().minify(css)
if (!minified.styles) {
return reject(minified.error)
}
resolve(minified.styles)
})
}

// display an error overlay when CSS build fails.
// this brilliant idea is taken from Mike Riethmuller / Supermaya
// @see https://github.com/MadeByMike/supermaya/blob/master/site/utils/compile-scss.js
renderError(error) {
return `
// display an error overlay when CSS build fails.
// this brilliant idea is taken from Mike Riethmuller / Supermaya
// @see https://github.com/MadeByMike/supermaya/blob/master/site/utils/compile-scss.js
renderError(error) {
return `
/* Error compiling stylesheet */
*,
*::before,
Expand Down Expand Up @@ -95,25 +95,25 @@ module.exports = class {
border: solid 2px red;
position: fixed;
}`
}
}

// render the CSS file
async render({ entryPath }) {
try {
const css = await this.compile({ file: entryPath })
const result = await this.minify(css)
return result
} catch (err) {
// if things go wrong
if (isProd) {
// throw and abort in production
throw new Error(err)
} else {
// otherwise display the error overlay
console.error(err)
const msg = err.formatted || err.message
return this.renderError(msg)
}
}
}
// render the CSS file
async render({ entryPath }) {
try {
const css = await this.compile({ file: entryPath })
const result = await this.minify(css)
return result
} catch (err) {
// if things go wrong
if (isProd) {
// throw and abort in production
throw new Error(err)
} else {
// otherwise display the error overlay
console.error(err)
const msg = err.formatted || err.message
return this.renderError(msg)
}
}
}
}
51 changes: 51 additions & 0 deletions src/assets/styles/components/_social-card.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
body.social-card {
background-color: $white;
color: $gray-950;
display: block;
margin: 0;

.box {
width: 1200px;
height: 630px;
position: relative;
background-color: $gray-50;
padding: 32px;
box-sizing: border-box;
display: flex;

.container {
background: $white;
color: $gray-950;
border-radius: 32px;
height: 100%;
width: 100%;
padding: 48px;
position: relative;
display: flex;

img {
border-radius: 100px;
position: absolute;
}

h1 {
width: 696px;
font-size: 70px;
display: flex;
align-items: center;
line-height: 5rem;
margin: 0;
}

p {
font-family: "Inter";
font-weight: 500;
font-size: 32px;
line-height: 3rem;
letter-spacing: -0.001em;
position: absolute;
bottom: 48px;
}
}
}
}
1 change: 1 addition & 0 deletions src/assets/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
@import "components/checkbox";
@import "components/writing/article-card";
@import "components/writing/header";
@import "components/social-card";

// Pages
@import "pages/home";
Expand Down
62 changes: 44 additions & 18 deletions src/includes/meta.njk
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,73 @@ endset -%}
<meta property="og:url" content="{{ absolutePageUrl }}"/>
<meta property="og:type" content="website"/>
<meta
property="og:description"
content="{{ description or meta.description }}"
property="og:description"
content="{{ description or meta.description }}"
/>
<meta property="og:site_name" content="{{ meta.title }}"/>
<meta property="og:locale" content="{{ meta.locale }}"/>
<meta name="author" content="{{ author.name }}"/>
<meta
property="og:image"
content="{{ 'https://afnizarnur.com/assets/images/meta-image.png' | url }}"

{% if page
.url
.startsWith('/writing/') %}
{% if page.url == '/writing/' or
page
.url
.startsWith('/writing/tags/') %}
<meta
property="og:image"
content="{{ 'https://afnizarnur.com/assets/images/meta-image.png' | url }}"
/>

<meta
property="twitter:image"
content="{{ 'https://afnizarnur.com/assets/images/meta-image.png' | url }}"
/>
{% else %}
<meta property="og:image" content="{% openGraphScreenshotURL %}"/>
<meta property="twitter:image" content="{% openGraphScreenshotURL %}"/>
{% endif %}
{% else %}
<meta
property="og:image"
content="{{ 'https://afnizarnur.com/assets/images/meta-image.png' | url }}"
/>
<meta
property="twitter:image"
content="{{ 'https://afnizarnur.com/assets/images/meta-image.png' | url }}"
/>
{% endif %}

{# Twitter #}
<meta property="twitter:card" content="summary_large_image"/>
<meta name="twitter:site" content="@{{ author.social.twitter.name }}"/>
<meta name="twitter:creator" content="@{{ author.social.twitter.name }}"/>
<meta property="twitter:title" content="{{ title or meta.title }}"/>
<meta property="twitter:description" content="{{ description or meta.description }}"/>
<meta
property="twitter:image"
content="{{ 'https://afnizarnur.com/assets/images/meta-image.png' | url }}"
property="twitter:description"
content="{{ description or meta.description }}"
/>
<meta property="twitter:url" content="https://afnizarnur.com/"/>

{# Favicon #}
<link
rel="apple-touch-icon"
sizes="180x180"
href="{{ '/assets/images/favicon/apple-touch-icon.png' | url }}"
rel="apple-touch-icon"
sizes="180x180"
href="{{ '/assets/images/favicon/apple-touch-icon.png' | url }}"
/>
<link
rel="shortcut icon"
href="{{ '/assets/images/favicon/favicon.ico' | url }}"
sizes="any"
rel="shortcut icon"
href="{{ '/assets/images/favicon/favicon.ico' | url }}"
sizes="any"
/>
<link rel="manifest" href="{{ '/site.webmanifest' | url }}"/>
<meta name="theme-color" content="#191a1b"/>

{# RSS Feed #}
<link
type="application/atom+xml"
rel="alternate"
href="{{ meta.url }}/feed.xml"
title="{{ meta.title }}"
type="application/atom+xml"
rel="alternate"
href="{{ meta.url }}/feed.xml"
title="{{ meta.title }}"
/>
23 changes: 23 additions & 0 deletions src/pages/social-card.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
pagination:
data: collections.writing
size: 1
alias: post
permalink: "social-card/{{ post.url }}/"
eleventyExcludeFromCollections: true
---

<html>
<head>
<link rel="stylesheet" href="{{ '/assets/styles/main.css' | url }}"/>
</head>
<body class="social-card">
<div class="box">
<div class="container">
<img src="{{ '/assets/images/afnizar-nur-ghifari.png' | url }}" alt="Afnizar Nur Ghifari" height="70" width="70" decoding="async"/>
<h1 class="headline">{{ post.data.title }}</h1>
<p>Afnizar Nur Ghifari</p>
</div>
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion src/pages/work-tags.njk
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ pagination:
data: collections
size: 1
alias: tag
addAllPagesToCollections: true
filter:
- works
- worksbyyear
- selected
eleventyComputed:
title: "{% set filteredWorks = collections.works | filterByTag(tag) %}{{ filteredWorks | length | pluralize('work') }} tagged with {{ tag }}"
permalink: /work/tags/{{ tag | slugify }}/
eleventyExcludeFromCollections: true
---

{% include "userinfo.njk" %}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/writing-tags.njk
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ pagination:
data: collections
size: 1
alias: tag
addAllPagesToCollections: true
filter:
- writing
eleventyComputed:
title: "{% set filteredWritings = collections.writing | filterByTag(tag) %}{{ filteredWritings | length | pluralize('post') }} tagged with {{ tag }}"
permalink: /writing/tags/{{ tag | slugify }}/
eleventyExcludeFromCollections: true
---

{% include "userinfo.njk" %}
Expand Down
1 change: 1 addition & 0 deletions src/robots.njk
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ eleventyExcludeFromCollections: true

User-agent: *
Disallow: /build.txt
Disallow: /social-card/*

Sitemap: {{ meta.url }}/sitemap.xml
7 changes: 7 additions & 0 deletions utils/shortcodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,12 @@ module.exports = {
} catch (error) {
return ""
}
},
openGraphScreenshotURL: function () {
const encodedURL = encodeURIComponent(
`https://afnizarnur.com/social-card${this.page.url}`
)
const cacheKey = `_${new Date().valueOf()}`
return `https://v1.screenshot.11ty.dev/${encodedURL}/opengraph/${cacheKey}`
}
}

0 comments on commit 3284c3e

Please sign in to comment.