DEV Community

Amna Anjum
Amna Anjum

Posted on

Turn Tweets Into Beautiful Images With <25 Lines of Code - A Practical Guide

Social platforms love visuals. Tweets perform great, but screenshots? They're messy. Cropped weird. Inconsistent. Hard to brand.

What if you could turn any tweet into a clean, polished, branded image with just a few lines of code?

In this tutorial, you'll learn how to convert tweets into beautiful social-ready graphics using a simple REST API — no browser automation, no manual screenshots, and definitely no fiddling with design tools.


Why Not Just Screenshot Tweets?

Traditional screenshot APIs:

  • Capture the whole browser with UI clutter
  • Break when Twitter's layout changes
  • Aren't consistent across devices
  • Give you zero control over branding

With a rendering-based endpoint, you can:

  • Apply your brand fonts, colors, and watermarks
  • Get a clean tweet layout every time
  • Automate the whole process
  • Use it for IG posts, LinkedIn quotes, newsletters, or app UI

This tutorial uses the Contentdrips API, but the concepts apply broadly.


What We're Building

By the end of this tutorial, you'll be able to extract tweet text from any tweet URL and convert it into a branded image like this:

Example tweet converted to branded image

The process involves two steps: extracting the tweet text using Twitter's API, then rendering it as a branded image using the Contentdrips Graphics Generation API.


Prerequisites

Before we start, you'll need:

  • Node.js (or any environment that supports fetch/HTTP requests)
  • A Twitter Developer account with API access (for extracting tweet text)
  • A Contentdrips API key (takes 30 seconds to get)
  • A template with a textbox labeled tweet_text

Getting Your Twitter API Access

  1. Go to Twitter Developer Portal
  2. Apply for a developer account (free tier works fine)
  3. Create a new app and generate your Bearer Token
  4. You'll use this to fetch tweet data

Getting Your Contentdrips API Key

  1. Go to Contentdrips Dashboard
  2. Sign up for free (no credit card required)
  3. Navigate to Contentdrips API in the sidebar
  4. Click "API Key" in the tabs
  5. Copy your token

API Documentation: https://developer.contentdrips.com/


Step 0: Prepare Your Template (One-Time Setup)

Before you start using the API, set up your template once inside Contentdrips:

Open Contentdrips App → Templates Design → Tweet Styles and pick any tweet-style template
OR open your template in the editor and click Automate to view the labels.

Make sure your textbox for the tweet content is labeled (example: tweet_text).

You only need to do this once — after it’s labeled, every API call will use it automatically.

Step 1: Extract Tweet Text from URL

First, we need to extract the tweet ID from the URL and fetch the tweet data:

// Extract tweet ID from URL
function getTweetId(tweetUrl) {
  const match = tweetUrl.match(/status\/(\d+)/);
  return match ? match[1] : null;
}

// Fetch tweet data from Twitter API
async function getTweetText(tweetUrl, twitterBearerToken) {
  const tweetId = getTweetId(tweetUrl);

  if (!tweetId) {
    throw new Error("Invalid tweet URL");
  }

  const response = await fetch(
    `https://api.twitter.com/2/tweets/${tweetId}`,
    {
      headers: {
        "Authorization": `Bearer ${twitterBearerToken}`
      }
    }
  );

  const data = await response.json();
  return data.data.text;
}

// Usage
const tweetUrl = "https://twitter.com/user/status/1234567890";
const tweetText = await getTweetText(tweetUrl, "YOUR_TWITTER_BEARER_TOKEN");
console.log("Tweet text:", tweetText);
Enter fullscreen mode Exit fullscreen mode

What just happened?

We extracted the tweet ID from the URL, made a request to Twitter's API v2, and retrieved the actual text content. Now we can pass this text to Contentdrips for rendering.


Step 2: Render the Tweet Text as an Image

Now that we have the tweet text, let's convert it into a branded image. Get a free API key without adding any credit card details at Contentdrips API Management:

async function renderTweetImage(tweetText, contentdripsApiToken, templateId) {
  const response = await fetch("https://generate.contentdrips.com/render", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${contentdripsApiToken}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      template_id: templateId,
      output: "png",
      content_update: [
        { 
          type: "textbox", 
          label: "tweet_text", 
          value: tweetText 
        }
      ]
    })
  });

  const job = await response.json();
  console.log("Job ID:", job.job_id);
  return job.job_id;
}
Enter fullscreen mode Exit fullscreen mode

What just happened?

You've told the Contentdrips API: "Please render this tweet text inside my template and give me a job ID so I can check when it's done."

The rendering happens asynchronously, which means you get an instant response with a job_id, and the actual image generation happens in the background.

Note: The content_update array should match the labels you defined in your template. If you labeled your textbox differently (e.g., tweet_content or text), use that label instead. You can find the exact payload structure by clicking the "AUTOMATE" button in your template editor.


Step 3: Poll the Job Status

Since rendering takes a few seconds, you need to check when the image is ready:

async function checkJobStatus(jobId, contentdripsApiToken) {
  const checkStatus = await fetch(
    `https://generate.contentdrips.com/job/${jobId}/status`,
    { 
      headers: { 
        "Authorization": `Bearer ${contentdripsApiToken}` 
      } 
    }
  );

  const statusData = await checkStatus.json();
  return statusData.status; // "queued", "processing", or "completed"
}
Enter fullscreen mode Exit fullscreen mode

Poll every 2-3 seconds — no need to hammer the server. Once the status returns "completed", you're ready for the final step.


Step 4: Retrieve the Final Image URL

Once the job is marked completed, grab your image:

async function getImageUrl(jobId, contentdripsApiToken) {
  const result = await fetch(
    `https://generate.contentdrips.com/job/${jobId}/result`,
    { 
      headers: { 
        "Authorization": `Bearer ${contentdripsApiToken}` 
      } 
    }
  );

  const data = await result.json();
  return data.export_url;
}
Enter fullscreen mode Exit fullscreen mode

You now have a direct CDN URL to your final PNG. Download it, embed it, post it to social media, or feed it into your workflow automation.


Real-World Use Cases

This isn't just a fun experiment. Here's where tweet-to-image conversion becomes genuinely powerful:

1. Automatic Instagram Posts

Trigger this API when a new tweet is published → send the image to Zapier or n8n → auto-publish to Instagram.

2. Social Proof Widgets

Pull positive customer tweets and convert them into branded graphics that live on your landing page or dashboard.

3. Weekly "Best Tweet" Graphics

Perfect for newsletters, blog recap posts, or LinkedIn content. Automate your weekly roundup.

4. Creator Tools

Build a SaaS feature where users paste a tweet URL and get a downloadable branded image instantly.

5. Batch Content Generation

Pipeline hundreds of tweets through templates for large-scale content campaigns. Great for agencies or multi-brand workflows.


⚙️ Template Tips for Best Results

If you want your images to look polished and shareable:

  • Label your textbox as tweet_url so the API knows where to inject the tweet content
  • Add a watermark or brand handle for attribution
  • Use consistent fonts across all your templates
  • Keep spacing and padding generous for readability
  • Use your brand colors for backgrounds

Clean, professional design → higher shareability → natural backlinks from people using your content.


Complete Working Example

Here's a production-ready function that combines everything:

// Extract tweet ID from URL
function getTweetId(tweetUrl) {
  const match = tweetUrl.match(/status\/(\d+)/);
  return match ? match[1] : null;
}

// Fetch tweet text from Twitter API
async function getTweetText(tweetUrl, twitterBearerToken) {
  const tweetId = getTweetId(tweetUrl);

  if (!tweetId) {
    throw new Error("Invalid tweet URL");
  }

  const response = await fetch(
    `https://api.twitter.com/2/tweets/${tweetId}`,
    {
      headers: {
        "Authorization": `Bearer ${twitterBearerToken}`
      }
    }
  );

  const data = await response.json();
  return data.data.text;
}

// Complete function: Tweet URL to Image
async function tweetToImage(tweetUrl, twitterToken, contentdripsToken, templateId) {
  try {
    // Step 1: Extract tweet text
    const tweetText = await getTweetText(tweetUrl, twitterToken);
    console.log("Extracted text:", tweetText);

    // Step 2: Submit render job
    const submitResponse = await fetch("https://generate.contentdrips.com/render", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${contentdripsToken}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        template_id: templateId,
        output: "png",
        content_update: [
          { type: "textbox", label: "tweet_text", value: tweetText }
        ]
      })
    });

    const job = await submitResponse.json();

    // Step 3: Poll for completion
    let status = "queued";
    while (status !== "completed") {
      const statusResponse = await fetch(
        `https://generate.contentdrips.com/job/${job.job_id}/status`,
        { headers: { "Authorization": `Bearer ${contentdripsToken}` } }
      );

      const statusData = await statusResponse.json();
      status = statusData.status;

      // Wait 2 seconds before checking again
      await new Promise(resolve => setTimeout(resolve, 2000));
    }

    // Step 4: Get final image URL
    const resultResponse = await fetch(
      `https://generate.contentdrips.com/job/${job.job_id}/result`,
      { headers: { "Authorization": `Bearer ${contentdripsToken}` } }
    );

    const resultData = await resultResponse.json();
    return resultData.export_url;

  } catch (error) {
    console.error("Error converting tweet to image:", error);
    throw error;
  }
}

// Usage
tweetToImage(
  "https://twitter.com/elonmusk/status/1234567890",
  "YOUR_TWITTER_BEARER_TOKEN",
  "YOUR_CONTENTDRIPS_API_TOKEN",
  "YOUR_TEMPLATE_ID"
).then(imageUrl => {
  console.log("Image ready:", imageUrl);
});
Enter fullscreen mode Exit fullscreen mode

Error handling tip: Always wrap API calls in try-catch blocks and handle cases where:

  • The tweet URL is invalid
  • The Twitter API rate limit is hit
  • The job fails during processing
  • Network errors occur

Why This Approach Wins

Let's compare the traditional workflow vs. the API workflow:

Traditional way:

  1. Open Twitter in browser
  2. Take a screenshot
  3. Open Photoshop or Canva
  4. Crop and edit
  5. Export and upload
  6. Repeat for every tweet

API way:

  1. Paste tweet URL
  2. Extract text with Twitter API
  3. Render with Contentdrips API
  4. Get branded image in 3 seconds

You've just eliminated 90% of manual work.


Next Steps and Extensions

Once you've got the basics down, you can:

  • Build a Chrome extension that converts tweets with one click
  • Create a Slack bot that renders tweets when someone posts a URL
  • Set up a serverless function (AWS Lambda, Vercel) that auto-generates images on a schedule
  • Integrate with Airtable or Notion for bulk tweet processing
  • Add this as a feature in your existing SaaS product

The API is flexible enough to fit into almost any workflow.


Additional Resources


Final Thoughts

Turning tweets into branded visuals used to require:

  • Manual screenshots
  • Design tools
  • Cropping and editing
  • Inconsistent results

With two simple APIs, you can automate the entire workflow and generate clean, consistent tweet graphics in seconds — whether you're building:

  • Creator tools
  • Marketing automation
  • Dynamic content generators
  • Social media management apps

This is one of the easiest ways to add high-value functionality to your product with minimal code.


Have you built something with this workflow? Drop a comment below — I'd love to see what you create.

If you found this helpful, consider bookmarking it for later or sharing it with your dev friends.

Top comments (0)