Better Bookmark Cards
After improving the Twitter cards on this site the other week, I wanted to do something similar with my more generic BookmarkCard components. These take a URL:
<BookmarkCard url="https://danny.is/now" />And render a nice-looking card like this:
This component and the fetch functions it uses were pretty unsophisticated, and I started noticing some issues with special characters in titles not rendering properly. Since this runs at build-time, I was fetching each page’s HTML on every build — several times over, since a bookmarked URL can appear on the note page, the home page, /notes and in the RSS feed — which occasionally got rate limited for domains like github.com. While addressing this I also added a few other bits:
- The code which extracts & cleans the title and description is much more robust.
- We now extract and show the favicon if it’s available.
- We extract and show the site name, author and published date if they’re available.
- Links to non-HTML files like PDFs show a label with the file type.
- Links to archive versions of pages on archive.ph or the Wayback Machine are labelled as such and attempt to grab their metadata from the original URL.
- Links which 404 at build-time are marked with a may be dead label.
The biggest change is that images are now downloaded and re-hosted here. Previously the cards hotlinked whatever og:image the page declared. Now they’re fetched, re-encoded to webp, and served from danny.is with appropriate width & height attributes. These aren’t committed in the repo, but they are cached across builds in a similar way to other images.
We also cache the raw <head> HTML for every bookmark card URL in node_modules/.astro/link-cache/ which avoids the need to refetch all of them on every single build.
Every state is rendered at /styleguide/components#bookmark-card.
danny.is