Turn a product feed into video ads automatically
Export your catalogue as a CSV, route rows with If/Else logic and render a video ad for every in-stock product. Sale versions and weekly refreshes included.
Somewhere in your ecommerce stack there is a product feed: a file listing everything you sell, with names, prices, stock levels and sale flags. It already powers your shopping listings and your catalogue ads. It could be powering your video ads too, and not the cropped-pack-shot kind.
This tutorial shows you how to turn that feed into properly designed video ads with Nubu: one ad per product, routed by stock, sale status and price, refreshed every time you export a new file. It is the ecommerce sequel to CSV to video ads, which covers the basics of piping a spreadsheet into a template. Read that first if you have not. This piece assumes you know how columns become pipes, and goes where feeds actually live: row routing and the refresh lifecycle.
Why product feed video ads all look the same
You can recognise a feed-generated ad from across the room. A square pack shot cropped into a coloured frame. The product title in a system font, truncated with an ellipsis. A price sticker, perhaps a slow zoom, a logo in the corner. Every product looks identical because every product went through the same crop.
That aesthetic is not a taste choice. It is a renderer limitation. Most product feed to video tools composite images in a lightweight renderer that can scale, fade and slide, so the ceiling on every output is a slideshow. The feed was never the problem; feeds are beautifully structured data. The problem is what happens after the feed.
Nubu renders through After Effects templates instead. A template is real motion design: layered scenes, brand typography, choreographed transitions, the same craft your hero campaign gets. The feed row does not dictate the design; it fills slots inside it. Product name, price and sale badge become editable layers in a designed sequence, and the difference between product 14 and product 15 is the data, not the quality.
That changes what ecommerce video ad automation means. It stops being "generate 500 acceptable slideshows" and becomes "run 500 products through the design your brand actually signs off".
Shape the export: one row per product
Feeds arrive in Nubu as CSV exports. Shopify, WooCommerce, Magento and every ERP worth its licence can export the catalogue as a CSV, and that file is your input. There is no live feed connector today (more on that honestly below), which means the shape of the export is entirely in your hands. Spend ten minutes on it and everything downstream gets easier.
Three rules:
One row per product. If you sell variants, decide what one ad means before you export. Usually that is one row per parent product carrying the hero variant's details, not forty rows of size permutations that would each demand their own video.
Clean headers. The header row becomes your column keys, tidied automatically ("Product Name" becomes product_name) and de-duplicated if two headers collide. Name headers like variables, because that is what they are about to become.
Typed values in routing columns. You will route rows with typed comparisons shortly, so keep stock_level a bare number (14, not "14 units"), keep price a bare number (89.99, not "£89.99 RRP") and keep on_sale a plain true or false. A value the router cannot evaluate is treated as false, which is safe but silent.
A working set of columns for this tutorial:
- product_name, the headline slot
- category, for grouping footage and looks
- price, for the price slot and tier routing
- on_sale, for the sale split
- stock_level, for the availability gate
- footage_ref, a human-readable pointer to each product's library clip
The limits are generous for an active catalogue: 10 MB, 5,000 rows and 40 columns per file, and exact duplicate rows collapse into one automatically. One shaping habit matters more than any limit: think in dimensions and content. Columns with a small set of repeated values (category, on_sale) make good dimensions, the axes your creative matrix expands along. Columns unique to each product (product_name, price) are content, the values that fill template slots. Nubu warns you if you pipe a column with around a hundred unique values into a dimension, because that is nearly always a mispicked column. Full column mechanics live in working with data.
Wire the feed into a flow
Create a flow and drop in a CSV node. If the node editor is new territory, the node editor tour covers the canvas itself; the short version is that flows are graphs where data flows into templates (flows overview).
A flow takes exactly one CSV node, by design: one feed, one flow, no ambiguity about where any value came from. The node accepts your file two ways: upload it directly, or select a CSV that already sits in your asset library (Nubu copies it into the flow, so later changes to the library file never silently change your ads). The node previews the first ten rows immediately and pages in more as you scroll.
| product | price |
|---|---|
| Aurora Trainers | 120 |
| Trail Runner X | 89 |
| City Slip-On | 64 |
Tick the columns you want to expose. Each becomes a pipeable output on the node. Now pipe:
- product_name into a Text node and price into a Value node. Every unique value appears as a locked, generated row with a count of how many feed rows it came from. Generated rows are locked because they are derived: you cannot edit them, but you can see all of them, and they behave exactly like rows you would have typed by hand.
- category into a dimension node such as Version, if you want one look per category. Generated category rows arrive the same way, each one a gate for its own chain.
Then auto-pairing does the wiring you would dread doing by hand. When two piped columns co-occur on the same rows, Nubu draws the connections between values that actually share a row: each price is wired to its own product, each product to its own category. Two hundred products wire themselves in the time it takes to read this sentence, and nothing can pair with a value it never shared a row with.
Route in-stock products only
Every routing recipe in this tutorial is one node: If/Else. It takes a piped column in, applies conditions, and sends rows out of a True or a False output. The node routes the column you pipe through it, while its conditions can test any column in the file, using typed comparisons. And anything the node cannot evaluate (a blank cell, text where a number should be) routes False, never True. That fail-safe direction is deliberate: broken data falls out of your ads, not into them.
The first rule every catalogue needs:
- Pipe product_name into an If/Else node.
- Set the condition stock_level greater than 0.
- Wire the True output onwards into your content chain. Leave False unwired.
The node shows live counts as you set the condition: 214 rows route True, 37 route False. Products with zero stock, and products whose stock cell is empty or mangled, simply never generate an ad. There is no cleanup step, because downstream they never existed.
Route sale items to the Sale version
Build two versions of your creative chain under a Version dimension: Standard and Sale. The Sale version carries the design your brand uses for discounts: the badge, the was-and-now price scene, the louder end card.
Then split the feed between them:
- Pipe product_name into an If/Else with the condition on_sale equals true.
- Wire the True output into the content nodes under the Sale version.
- Wire the False output into the content nodes under Standard.
At build time each product generates down exactly one path. Sale products get the Sale treatment, everything else gets Standard, and the fail-safe direction earns its keep: a product whose on_sale cell is blank routes False and receives the Standard version. Your automation cannot invent a discount claim, which is precisely the direction you want compliance mistakes to fall.
Route hero SKUs to the premium template
Not every product deserves the same production value, and with routing it does not have to get it.
- Pipe product_name into an If/Else with the condition price greater than 100.
- True feeds a chain built on your premium template: the longer edit, more scenes, the considered typography.
- False feeds the standard template.
The comparison is typed, so 89.99 against 100 resolves as numbers, not strings. And the threshold does not have to be price. Add a margin or priority column to the export and route on that instead; the feed is yours to shape, and any column can become a routing axis.
Chain If/Else nodes for compound rules
Real merchandising rules are compound, and there are two ways to compose them.
Conditions inside one node AND-combine. "In-stock sale items" is a single If/Else holding two conditions, stock_level greater than 0 and on_sale equals true, and a row must pass both to route True.
Chaining handles everything else. Each If/Else routes the one column piped into it, so multi-step logic is a ladder of nodes: wire the False output of one into the input of the next. A three-tier catalogue looks like this:
- First node: price greater than 250. True feeds the premium chain.
- Its False output feeds a second node: price greater than 80. True feeds the mid-tier chain.
- False again feeds the clearance chain.
Every product flows down exactly one branch, the live counts show how many land in each tier, and the whole decision tree stays visible on the canvas rather than buried in a settings panel.
You do not have to wire any of this by hand, either. Describe the feed and the rules to Nubu's AI assistant ("every in-stock product, sale items on the Sale version, anything over £250 on the premium template") and it drafts the entire routed flow as a proposal card, test-built by the same engine as the real Build, with the expected creative count visible before you approve a thing. It can also search your asset library for the right product footage and tag what it finds. What it cannot do is render, publish or spend; those stay behind your explicit approval. The full picture is in the AI campaign builder guide and AI asset search.
Give every product real footage
Text and prices ride in on pipes. Footage does not: footage nodes take clips from your asset library, not CSV columns, and Nubu will not fetch media from URLs in your feed. That constraint is worth designing for rather than fighting.
The working-column pattern makes it manageable. That footage_ref column you added to the export is never piped anywhere; it is the audit trail. Each cell names the library asset the product should carry ("SKU-1042 hero loop"), so whoever wires the flow matches clips by name instead of memory, and anyone reviewing the flow later can check a generated row against the sheet in seconds.
Then wire footage at the coarsest level that stays honest:
- Category-level footage. One set of clips per category, wired once under the category dimension. Two hundred products across eight categories means eight footage decisions, not two hundred, and per-product uniqueness comes from the text, price and colour pipes.
- Hero-level footage. The premium chain from the price recipe probably warrants per-product clips. That is a short list by construction, which is rather the point of routing.
- Generated fills. Where the library has gaps, Nubu's AI image and video nodes can generate product scenes into the library, at which point they are ordinary assets like everything else.
If the library is large, name your uploads to match the footage_ref convention before you start; search does the rest.
Preview the matrix, then build
Before you commit anything, look at it. Drop a Preview node onto a chain and you get real frames for a routed row, rendered through the same pipeline the final build uses, without spending a build. Spot-check the extremes: your longest product name, your highest price, a sale item, a clearance item.
Then press Build. The build is stricter than the canvas, in ways feeds specifically need:
- Row-impossible combinations are pruned. The Sale version can never pair with a full-price product, because no feed row satisfies both sides of that pairing. You cannot accidentally build the cross product of everything with everything.
- Every piped value is re-verified against its filtered column at build time, not assumed from upload day.
- Builds cap at 5,000 creatives and are deterministic. The same file through the same graph produces the same creatives with stable identities, which is about to matter enormously.
The output is a grid of renders to review and approve, the same approval flow as everything else in Nubu (building a creative). Approved creatives deliver as paused Meta ads or as paused Google Demand Gen or Performance Max asset groups on the Business+ plan, or you export a ZIP with a manifest CSV that maps every file back to its feed row.
If you fancy following along with your own export, create a workspace and open a flow; pricing shows which plans include data nodes.
The refresh: replace the file, keep what holds
Here is the part that makes this a system rather than a one-off batch job, and the part basic CSV piping never had to answer.
Next Monday, merchandising has moved. Prices changed, twelve products sold out, nine launched, two got renamed. You do not rebuild the flow. You export a fresh CSV and replace the file on the CSV node. Everything derives again from the new file, immediately: generated rows, If/Else counts, auto-pairings, all of it. Nothing lingers from the old file, so there is no stale value to hunt down and no sync step to forget. The graph is the standing machine; the CSV is the moving part.
Run the build again and watch what determinism buys you:
- Unchanged products keep their renders. Same row, same graph, same creative identity: nothing re-renders without a reason, and your approved ads stay approved.
- Changed products become revisions. A price drop produces a new revision of the same creative, not a confusing duplicate sat beside the old one. Anything already rendered, or mid-render, survives the rebuild untouched.
- Sold-out products drop out on their own. Their stock_level hit 0, the in-stock rule routes them False, and the new build simply does not contain them. Nobody files a ticket to take down the ad for a product you cannot ship.
- New products appear on their own. New rows generate new values, auto-pairing wires them into place, and the next build includes them. Review, approve, deliver.
And when a refresh breaks something, Nubu refuses loudly instead of guessing. Say you hand-wired a pipe from a specific product value, and this week's export renamed that product. The stale pipe wears a "Value gone" label on the canvas, and the build refuses to run until you resolve it. Rewire it or delete it; what you cannot do is ship an ad built on a value that no longer exists in the feed. Failing loudly beats failing quietly in every advertising system ever built.
Match the cadence to your merchandising rhythm. Weekly suits most catalogues: export, replace, glance at the routing counts for surprises, build, approve the delta. The loop settles into minutes, because you only ever review what changed.
What this will not do
Tools earn trust at their edges, so here are this one's.
- It is a CSV export, not a live sync. There are no live feed connectors today. The refresh happens when you, or a scheduled export on your side, replace the file. If stock swings hourly and an hours-stale ad is a genuine problem, run a daily rhythm and keep the in-stock rule conservative; this is a cadence tool, not a real-time one.
- One CSV node per flow. One feed drives one flow. Separate brands, regions or catalogue slices belong in separate flows, which in practice keeps each flow legible anyway.
- Feed media stays a reference. Image URLs in the export are never fetched. Footage and stills come from your asset library or from the AI generation nodes, and footage_ref is a pointer for humans, not a download instruction.
- The limits are real. 10 MB, 5,000 rows, 40 columns, 5,000 creatives per build. If your catalogue runs to 80,000 SKUs, feed the flow the merchandised slice that deserves video this week, not the warehouse. The routing recipes are exactly the tool for choosing that slice.
Start with the top fifty
Do not start with the whole catalogue. Export your fifty most merchandised products with the six columns from this tutorial. One template, the in-stock rule, the sale split. Build, review the grid, approve, and deliver a ZIP or a set of paused ads. That first pass takes an afternoon, and most of it is shaping the export.
Then add the premium tier, the category footage and the Monday replace-and-rebuild habit. By the third refresh the flow is infrastructure: the feed moves, the ads follow, and the only manual step left is the one that should stay manual, your approval.
Create your workspace and bring an export.