DEV Community

Cover image for How I built a Social Recipe Extractor that turns short-form video links into structured recipes
Rusu Ionut
Rusu Ionut

Posted on

How I built a Social Recipe Extractor that turns short-form video links into structured recipes

I recently built a feature for https://recipe-finder.org that takes a TikTok, Instagram, or YouTube cooking link and turns it into a structured recipe.

The goal was simple: recipe inspiration lives on social platforms, but the actual cooking steps are usually buried inside captions, spoken instructions, or fast cuts. I wanted a workflow where a user pastes a link and gets back something usable: a recipe title, ingredient list, instructions, and a cleaner format for the rest of the product.

The Flow

The core user journey is straightforward:

  1. The user pastes a supported social video URL.
  2. The frontend sends that URL to a protected backend endpoint.
  3. The backend normalizes the link, fetches available source metadata and text, and runs an extraction pass.
  4. The result is converted into a structured recipe object.
  5. The app returns a clean recipe view, keeps recent imports in history, and can reuse cached results for repeated links.

What makes this interesting isn't just the form inputβ€”it's the cleanup step between raw social content and something a user can actually cook from.

Here is a look under the hood at how it's built using Vue 3, TypeScript, and Node.js/Express.


1. Frontend Entry Point

The feature lives behind authentication and opens as a dedicated page in the app. The page itself stays simple and hands the main workflow to a dedicated Social Recipe Extractor component.

To keep the UI predictable and sleek (opting for a dark mode aesthetic with vibrant orange accents for active states), the component manages four main states:

  • The pasted social link
  • Loading and error feedback
  • The extracted recipe result
  • Recent import history and usage state

This keeps the input on the left, the result on the right, and prior imports available without mixing feature logic across multiple pages.

2. Backend-Owned Extraction Flow

The frontend does not parse social content directly. Instead, it sends the link to a backend route dedicated to social recipe extraction.

That backend layer is responsible for:

  • Validating the request
  • Normalizing the URL into a canonical form
  • Checking whether a usable cached import already exists
  • Fetching source metadata and extracted text from the target platform
  • Transforming unstructured content into a recipe-shaped response
  • Returning a stable payload the frontend can render safely

This is the right ownership boundary because platform parsing, rate control, caching, and extraction quality all belong on the server. The frontend only ever deals with a typed response.

3. Structured Extraction

The most important design choice was ensuring the pipeline doesn't stop at "grab some text from the page." It pushes the output into a highly structured shape:

  • Recipe title
  • Prep time
  • Ingredients
  • Instructions
  • Normalized ingredients
  • Source metadata (platform, thumbnail, title, author)

This matters because a structured result is much easier to reuse than a raw text dump. It allows the data to power future features without rebuilding the extraction logic each time.

4. Normalization and Cleanup

Social content is inherently messy. Titles contain hashtags, descriptions are noisy, and ingredient mentions are often incomplete or informal.

The implementation handles this by cleaning and normalizing content before and after extraction:

  • URL normalization ensures equivalent links map to the same import record.
  • Title cleanup prevents social-platform suffixes and noisy text from leaking into the recipe title.
  • Whitespace and escaped-text cleanup is applied before extraction.
  • Ingredient normalization makes the output more consistent for downstream product use.

This cleanup layer is where a lot of the actual product quality is realized.

5. Caching and History

Two product decisions make the feature feel significantly faster and more useful:

  1. Cached imports prevent unnecessary repeat processing for the same normalized link.
  2. Import history gives users a lightweight library of recently extracted recipes.

The extractor isn't just a one-shot tool; it becomes a reusable workflow inside the product.

6. Premium-Friendly Usage Model

Finally, the feature returns usage information along with the extraction result. That allows the UI to immediately show whether the user can continue importing, how much of their current allowance is used, and when an upgrade prompt should appear.

This is a much better user experience than hard-failing late in the flow, as the interface can explain the state before the user hits a dead end.


Wrapping Up

This is one of those features where the product value comes purely from reducing friction. People already save recipes from social media. The real improvement is turning that saved link into something searchable, reusable, and easier to cook from.

If I were extending it further, the next logical step would be connecting the extracted, structured recipe directly into grocery list generation, smart meal planning, and nutrition analysis.

Top comments (0)