DEV Community

Sebastian Casvean
Sebastian Casvean

Posted on • Originally published at zenndra.com

Add a Live Medium Writing Widget to Any Homepage

Add a Live Medium Writing Widget to Any Homepage

Visitors decide in seconds if you ship ideas. A stale “Blog” link hurts credibility; three real essay titles with dates does the opposite.

This builds a writing widget—not a full embed—ideal for homepages and landing pages.

Tool outcome: A cached API route /api/writing + a 3-card UI you can drop into any stack.


Widget vs full embed

Pattern Where Goal
Widget Homepage Tease; link to Medium or on-site posts
Full embed /writing/[slug] Keep readers on your domain

For full posts see embed Medium articles.


Server route (Next.js App Router example)

// app/api/writing/route.js
export const revalidate = 1800; // 30 min

const API = 'https://api.zenndra.com';

export async function GET() {
  const headers = { Authorization: `Bearer ${process.env.ZENNDRA_API_KEY}` };
  const handle = process.env.MEDIUM_USERNAME;

  const idRes = await fetch(`${API}/user/id_for/${handle}`, { headers, next: { revalidate: 86400 } });
  const { user_id } = await idRes.json();

  const listRes = await fetch(`${API}/user/${user_id}/articles`, { headers, next: { revalidate: 1800 } });
  const { articles } = await listRes.json();

  const latest = (articles ?? []).slice(0, 3).map((a) => ({
    id: a.id,
    title: a.title,
    url: a.url,
    published_at: a.published_at,
    preview: a.preview ?? '',
  }));

  return Response.json(latest);
}
Enter fullscreen mode Exit fullscreen mode

Never call third-party APIs from the browser with your secret key—always proxy server-side.


React cards

export function WritingWidget({ posts }) {
  return (
    <section aria-labelledby="writing-heading">
      <h2 id="writing-heading">Writing</h2>
      <ul className="writing-grid">
        {posts.map((p) => (
          <li key={p.id}>
            <time dateTime={p.published_at}>
              {new Date(p.published_at).toLocaleDateString()}
            </time>
            <a href={p.url}>{p.title}</a>
            {p.preview && <p>{p.preview}</p>}
          </li>
        ))}
      </ul>
      <a href="/writing">View all →</a>
    </section>
  );
}
Enter fullscreen mode Exit fullscreen mode

Performance tips

  • Fetch at build or edge with TTL—do not block LCP.
  • Use consistent card height; real dates beat “Updated 2022.”
  • Optional: pull hero image from article metadata when you want a magazine layout.

Keywords

medium portfolio widget, show medium posts on website, medium latest articles api, developer homepage writing section.


Further reading

Top comments (0)