A zero-script way for embedding tweets in your SvelteKit app

  • sveltekit
  • Software Development

Published on | Last updated:

In this blog post, I will provide you with a better way to embed tweets in your SvelteKit app, The tweet will be generated statically on the server. Without any additional scripts or iframe elements, and without sacrificing performance or having layout shifts anymore.

In the last month, Vercel announced the new react-tweet package for rendering statically generated tweets in your Next.js app. In the pages directory, it works by requesting the Twitter syndication API server-side before the page load. For React Server Components, the tweet is fetched and rendered server-side in the relevant component.

I thought making a SvelteKit version would be cool! And I wanted to use the same on my blog, hence, I made the sveltekit-tweet package.

Let’s dive into the implementation details to get it running on your website. We will begin with the most basic example, then we will head into adding tweets to your markdown files.

Begin by installing the `sveltekit-tweet`` package via pnpm - or npm/yarn, depending on your flavor of choice.

pnpm add sveltekit-tweet@latest

And in +page.server.ts, we import the getTweet function from sveltekit-tweet/server

import type { PageServerLoad } from './$types';
import { getTweet } from 'sveltekit-tweet/server';

export const load = (async () => {
	const tweetId = '1694201062717034868'; // You'll find it in the tweet URL
	const tweet = await getTweet(tweetId);

	return { tweet };
}) satisfies PageServerLoad;

The tweetId could be directly extracted from the URL you want to embed, and the getTweet function will fetch the tweet info using Twitter’s / X’s API. This function is a server-only function, it won’t be imported into your client-side script (which is a good thing).

The last step is to render what you get in your +page.svelte component:

<script lang="ts">
	import { Tweet } from 'sveltekit-tweet';
	import type { PageData } from './$types';

	export let data: PageData;

	const tweet = data.tweet;
</script>

<Tweet {tweet} />

Result:

Looks good, right? Now let’s head into embedding tweets in your markdown files, which is the cooler and more usable option. If you use a tool like mdsvex, you can add tweets to your articles this way:

> A quoted text followed by a tweet:

<div data-tweet="1694201062717034868" />

The only requirement is to use the renderTweets function, in +page.server.ts we have the following:

export const load: PageServerLoad = async ({ params }) => {
	try {
		// Import the markdown file
		const post = await import(`../blog/posts/${params.slug}.md`);

		// Render markdown file into HTML
		let content = render(post.default).body;

		// This will render all tags with data-tweet=”…” to statically generated tweets
		content = await renderTweets(content, fetchedTweets);

		return {
			content,
			meta: post.metadata,
			slug: params.slug
		};
	} catch (e) {
		throw error(404, `Could not find ${params.slug}`);
	}
};

The renderTweets function will transform all tags with data-tweet attribute be rendered using @html expression:

<script>
	export let data;
</script>

<article class="...">
	<main class="...">{@html data.content}</main>
</article>

Result:

A quoted text followed by a tweet:

SvelteKit is amazing!

Reply

And that’s it! Now you can embed without having to worry anymore, and without any headache or poor performance metrics.

© 2023 Fayez Nazzal. All rights reserved.
Social Links:
fayez@fayez.io