Why Google’s recipe results are meaningless.

Some recipes for cornbread, and some burnt cornbread.
Photo illustration by Slate. Photos by Getty Images Plus and Google.

Meathead Goldwyn has some long-standing beef with Google.

For the past nine years, the pitmaster and publisher of AmazingRibs.com—one of the internet’s leading authorities on all things barbecue—has warned against the tyranny of Google recipe rankings, which determine how and what millions of Americans cook.

Among other things, Google’s algorithms decide which versions of canonical dishes get prime billing in its search results. The search engine cherry-picks and spotlights only the culinary data points it considers important in its “rich” result links and recipe carousels. Google even displays a handy five-star rating alongside recipes from most major food sites, providing a quick shorthand for quality and eliminating the need to click through infinite variations of a dish. If you’re searching for cornbread recipes, you’re probably just going to click the one with five stars or the most ratings next to it.

But recipe ratings, like much of the “structured data” that Google privileges in its search results, often say less about the caliber of a recipe than they do about who published it. Sites supply the user-generated star ratings that Google pulls, and there are plenty of ways to skew them. Doing so doesn’t change a site’s place in the search rankings, but it does affect how many searchers click through—and, arguably, exposes the emptiness of the entire rating system.

To test that notion, I scraped more than 2,000 Google-ranked recipe ratings from a dozen popular cooking sites in early December. As of this writing, AllRecipes.com—the “distinctly unglamorous,” crowdsourced recipe bank best known for its users’ creative use of canned soups—commands higher average star ratings than both NYT Cooking and Bon Appétit do.

“I think I was the canary in the coal mine—the first food writer to warn about” how Google displays recipes in search results, said Goldwyn, who first wrote about the “pain” and “panic” of the site’s recipe search system in 2011. Since then, he has watched some of his site’s best-loved recipes slide off the first page of Google results, supplanted by “oven-baked” barbecue and “crockpot” ribs.

“But it’s Google’s world, and we just live in it,” Goldwyn said. “If you’re trying to make a living on the internet, you have to worship Google.”

It’s difficult to overstate the power Google has over food publishers: Most major food and recipe sites derive two-thirds or more of their visitors from the search engine, said Faith Durand, a digital food publishing veteran and editor in chief of the Kitchn. The holy grail, for recipe sites of any size, is the featured recipe carousel at the top of Google’s search results page.

Those three slots on desktop, and four on mobile, earn 75 percent of the clicks on any given search term, from “barbecue” to “vegan tomato soup,” said Liane Walker, the managing director of the membership-based consultancy Foodie Digital. Walker’s two-year-old firm is one of several agencies in a growing microindustry aimed at helping food bloggers boost their search engine optimization. As the food publishing field has grown more crowded, publishers have fought harder to access the legions of home cooks using Google search.

“Her life’s work,” Walker said of one client, without a trace of irony, “has gone into getting on the first page for sourdough bread. It took six years.”

Like all SEO strategies, the process of ranking a recipe on Google is both archaic and tedious. Food publishers must first play by all the regular rules of the Google algorithm, accounting for factors like site load time (fast), dwell time (high), and backlinks (numerous).

To land a recipe in the almighty carousel, publishers also need to adhere to an exacting set of data-formatting specifications called “recipe schema,” which standardize recipes across websites so that Google and other tech companies can parse them. Ratings are one possible attribute of recipe schema; so too are yield, nutrition, ingredients, and cook time, which Google also surfaces in “rich” search results—links jazzed up with photos and other contextual information, which tend to see far more clicks than their plane Jane neighbors.

But there’s been little scrutiny of the quality and the usefulness of Google’s recipe data, even as it ferries tens of millions of home cooks around the web. Star ratings are particularly suspect, as they are collected, moderated, and supplied by site publishers—who arguably have nothing but incentive to inflate them. (In a statement, Google said it penalizes publishers “if we find that a website has intended to deceive people with review snippets.”)

High ratings don’t always mean a recipe is good, and low ratings—of the sort that plague Martha Stewart, for instance—don’t mean a recipe is bad.

Even if a recipe’s ratings do reflect the opinions of its reviewers, that’s often less a measure of recipe quality than a sign of how skilled a publisher is at ginning up rave reviews from fans and disincentivizing bad reviews from critics. Sites that don’t actively moderate their comments sections, for instance, tend to have far lower recipe ratings than those that do—a product of both healthier comment section culture and fewer fake or drive-by reviews.

But there’s no industry standard for what counts as a fair or ethical level of moderation; every publication plays by its own rules. At Foodie Digital, for instance, Walker recommends her bloggers delete ratings and reviews in cases where the commenter is abusive or has significantly altered a recipe, and that they discourage bad scores by requiring a comment whenever a reviewer leaves a rating below five stars. That latter feature comes standard in Recipe Maker, the most popular web design plug-in for generating recipe schema.

At AmazingRibs.com, meanwhile—where recipes averaged 3.77 stars in my sample—a message asks readers not to rate a recipe until after they’ve cooked it but doesn’t require that they comment or log in. At New York Times Cooking (4.46 stars), newsroom editors cull abuse and “unproductive” comments, said Emily Weinstein, the vertical’s editor. But editors don’t touch recipe ratings and have no way to know if reviewers cooked the recipe before rating it.

In other words, high ratings don’t always mean a recipe is good, and low ratings—of the sort that plague domestic empress Martha Stewart, for instance—don’t mean a recipe is bad. Stewart averages 3.49 stars across the first 150 recipe results for Martha Stewart Living, a particularly poor showing when you consider that online reviews, on balance, tend to be pretty generous.

Does that mean Stewart’s team of food editors and recipe developers can’t cook? That her audience, which skews older, is not sufficiently motivated to leave reviews? Or does it really signal, as Walker suspects, that Martha’s publisher hasn’t “adequately resourced” comment section moderation? In a statement, Meredith Corp., which publishes Martha Stewart Living, said that the company requires users to log in before rating recipes and that it has “filtering and content moderation capabilities” to keep things from getting abusive or explicit.

“There are so many confounding factors around this data,” said Durand, of the Kitchn, where recipe raters are required to log in and the average recipe earns around 4.3 stars. “I would, no pun intended, always take recipe ratings with a grain of salt.”

But to Goldwyn, the AmazingRibs guy, almost any attempt to convert recipes into signals for search risks cheapening them. He hates the apparent widgetization of something he considers a craft. “The great MFK Fisher would not be found by Google,” Goldwyn likes to say, by which he means that a lot of classic recipes would not perform well in an industry that demands teams of data engineers, community moderators, and search engine consultants.

And yet, Goldwyn understands there’s no use resisting Google. In the past five years alone, he’s spent $300,000 rebuilding his site to Google’s specifications. In January, he’ll relaunch the site again, this time using Recipe Maker, which promises clean recipe schema and more intensive moderation of reviews and star ratings.

“It’s interesting,” Goldwyn said archly. “Engineers are telling chefs how to write and publish recipes.”

nnx3c!-- Rubicon Project Ad Tag --x3en


nn")),c=d(m[i.size_id].split("x").map(function(e)return Number(e)),2),s.width=c[0],s.height=c[1]),s.rubiconTargeting=(Array.isArray(i.targeting)?i.targeting:[]).reduce(function(e,t)return e[t.key]=t.values[0],e,rpfl_elemid:f.adUnitCode),t.push(s)):n.logError("Rubicon: bidRequest undefined at index position:".concat(o),r,e),t,[]).sort(function(e,t)return(t.cpm)},getUserSyncs:function(e,t,r,n)if(!x&&e.iframeEnabled)var i="";return r&&"string"==typeof r.consentString&&("boolean"==typeof r.gdprApplies?i+="?gdpr=".concat(Number(r.gdprApplies),"&gdpr_consent=").concat(r.consentString):i+="?gdpr_consent=".concat(r.consentString)),n&&(i+="".concat(i?"&":"?"https://slate.com/technology/2020/12/,"us_privacy=").concat(encodeURIComponent(n))),x=!0,type:"iframe",url:"https://".concat(g.syncHost,transformBidParams:function(e)return n.convertTypes(accountId:"number",siteId:"number",zoneId:"number",e)};function v(e,t)t.refererInfo.referer;return e.params.secure?r.replace(/^http:/i,"https:"):rfunction y(e,t)var r=e.params;if("video"===t)var i=[];return r.video&&r.video.playerWidth&&r.video.playerHeight?i=[r.video.playerWidth,r.video.playerHeight]:Array.isArray(n.deepAccess(e,"mediaTypes.video.playerSize"))&&1===e.mediaTypes.video.playerSize.length?i=e.mediaTypes.video.playerSize[0]:Array.isArray(e.sizes)&&0‘;var i,o,h=function(e)var t=0=e&&t.innerWidth‘+v.vast_url+”“:v.vast_string&&(y=v.vast_string),g.pre_market_bids.push(id:v.deal_id,seatbid:[bid:[impid:Date.now(),dealid:v.deal_id,price:v.price,adm:y]],cur:v.currency,ext:event_log:[])}var h=n.getBidIdParameter(“mimes”,e.params)||[“application/javascript”https://slate.com/technology/2020/12/,”video/mp4″https://slate.com/technology/2020/12/,”video/webm”],_=id:e.bidId,secure:l,video:w:p,h:f,ext:g,mimes:h;””!=n.getBidIdParameter(“price_floor”,e.params)&&(_.bidfloor=n.getBidIdParameter(“price_floor”,e.params)),””!=n.getBidIdParameter(“start_delay”,e.params)&&(_.video.startdelay=0+Boolean(n.getBidIdParameter(“start_delay”,e.params))),””!=n.getBidIdParameter(“min_duration”,e.params)&&(_.video.minduration=n.getBidIdParameter(“min_duration”,e.params)),””!=n.getBidIdParameter(“max_duration”,e.params)&&(_.video.maxduration=n.getBidIdParameter(“max_duration”,e.params)),””!=n.getBidIdParameter(“placement_type”,e.params)&&(_.video.ext.placement=n.getBidIdParameter(“placement_type”,e.params)),””!=n.getBidIdParameter(“position”,e.params)&&(_.video.ext.pos=n.getBidIdParameter(“position”,e.params)),e.crumbs&&e.crumbs.pubcid&&(c=e.crumbs.pubcid);var S=navigator.language?”language”:”userLanguage”,I=id:s,imp:_,site:id:””,page:a,content:”content”,device:h:screen.height,w:screen.width,dnt:n.getDNT()?1:0,language:navigator[S].split(“-“)[0],make:navigator.vendor?navigator.vendor:””,ua:navigator.userAgent,ext:wrap_response:1;n.getBidIdParameter(“number_of_ads”,e.params)&&(I.ext.number_of_ads=n.getBidIdParameter(“number_of_ads”,e.params));var A=;return 1==n.getBidIdParameter(“spotx_all_google_consent”,e.params)&&(A.consented_providers_settings=u),t&&t.gdprConsent&&(A.consent=t.gdprConsent.consentString,void 0!==t.gdprConsent.gdprApplies&&n.deepSetValue(I,”regs.ext.gdpr”,t.gdprConsent.gdprApplies?1:0)),t&&t.uspConsent&&n.deepSetValue(I,”regs.ext.us_privacy”,t.uspConsent),n.deepAccess(e,”userId.id5id.uid”)&&(A.eids=A.eids||[],A.eids.push(source:”id5-sync.com”,uids:[id:e.userId.id5id.uid],ext:e.userId.id5id.ext)),c&&(A.fpc=c),e&&e.schain&&(I.source=ext:schain:e.schain),e&&e.userId&&e.userId.tdid&&(A.eids=A.eids||[],A.eids.push(source:”adserver.org”,uids:[id:e.userId.tdid,ext:rtiPartner:”TDID”])),n.isEmpty(A)||(I.user=ext:A),method:”POST”,url:”https://search.spotxchange.com/openrtb/2.3/dados/”+s,data:I,bidRequest:t})},interpretResponse:function(e,t){var r=[],i=e.body;return i&&n.isArray(i.seatbid)&&n._each(i.seatbid,function(e){n._each(e.bid,function(e){var a=;for(var c in t.bidRequest.bids)e.impid==t.bidRequest.bids[c].bidId&&(a=t.bidRequest.bids[c]);n._each(a.params.pre_market_bids,function(t)t.deal_id==e.id&&(e.price=t.price,i.cur=t.currency));var d=”USD”,cpm:e.price,creativeId:e.crid;d.meta=d.meta||,e&&e.adomain&&0t?e:tfunction d(e,t,n)!e.preload&&e.preloadThreshhold&&function(e,t,n,i)return t.top<=i+n&&u(e)(t.target,t.rect,e.preloadThreshhold,n)&&(e.preload=!0,setTimeout(function()e.trigger("preload",new r("preload",t)),15))function c(n)function u(e)return e&&null!==e.offsetParent&&!e.getAttribute("hidden")&&"none"!==getComputedStyle(e).display&&"hidden"!==getComputedStyle(e).visibilityfunction f(e,t)return s(t,l(e.bottom,0))-s(l(e.top,0),t)(o=function(e,t)t=t).prototype=destroy:function()h.splice(h.indexOf(this),1),i.enable(o.prototype),r=function(e,t)var n=this;this.type=e,Object.keys(t).forEach(function(e)n[e]=t[e]),e.addEventListener("scroll",n(function()h.forEach(c),200)),this.getPageOffset=function(e)for(var t=e.offsetLeft,n=e.offsetTop;e=e.offsetParent;)t+=e.offsetLeft,n+=e.offsetTop;returnleft:t,top:n,this.getLinearSpacialHash=function e(t,n,i,o),this.getVerticallyVisiblePixels=f,this.getViewportHeight=function()return t.innerHeight,this.getViewportWidth=function()e.body.clientWidth,this.isElementNotHidden=u,this.isElementInViewport=function(n),this.Visible=o]); }, ]; require=(function e(t,n,r){function s(o,u)if(!n[o])if(!t[o])var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",fvar l=n[o]=exports:;t[o][0].call(l.exports,function(e)var n=t[o][1][e];return s(n?n:e),l,l.exports,e,t,n,r)return n[o].exportsvar i=typeof require=="function"&&require;for(var o=0;o= o.length) return done: true ; return done: false, value: o[i++] ; , e: function e(_e) throw _e; , f: F ; throw new TypeError(“Invalid attempt to iterate non-iterable instance.nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.”); } var normalCompletion = true, didErr = false, err; return s: function s() it = o[Symbol.iterator](); , n: function n() var step = it.next(); normalCompletion = step.done; return step; , e: function e(_e2) didErr = true; err = _e2; , f: function f() try if (!normalCompletion && it.return != null) it.return(); finally if (didErr) throw err; ; }

function _unsupportedIterableToArray(o, minLen) n === “Set”) return Array.from(o); if (n === “Arguments”

function _arrayLikeToArray(arr, len) if (len == null

function mountLegacyServices()
Object.keys(window.modules).filter(function (key)
return typeof key === ‘string’ && key.match(/.legacy$/);
).forEach(function (key)
return window.require(key);

function tryToMount(fn, el, name)
fn(el); // init the controller
catch (e)
var elementTag = el.outerHTML.slice(0, el.outerHTML.indexOf(el.innerHTML));
console.error(“Error initializing controller for “”.concat(name, “” on “”).concat(elementTag, “””), e);

* mount client.js component controllers

function mountComponentModules() {
Object.keys(window.modules).filter(function (key)
return typeof key === ‘string’ && key.match(/.client$/);
).forEach(function (key)
var controllerFn = window.require(key);

if (typeof controllerFn === ‘function’)
var name = key.replace(‘.client”https://slate.com/technology/2020/12/,”‘),
instancesSelector = “[data-uri*=”_components/”.concat(name, “/”]”),
defaultSelector = “[data-uri$=”_components”.concat(name, “”]”),
instances = document.querySelectorAll(instancesSelector),
defaults = document.querySelectorAll(defaultSelector);

var _iterator = _createForOfIteratorHelper(instances),

for (_iterator.s(); !(_step = _iterator.n()).done;)
var el = _step.value;
tryToMount(controllerFn, el, name);

catch (err)

var _iterator2 = _createForOfIteratorHelper(defaults),

for (_iterator2.s(); !(_step2 = _iterator2.n()).done;)
var _el = _step2.value;
tryToMount(controllerFn, _el, name);

catch (err)

} // Make sure that a `window.process.env.NODE_ENV` is available in the client for any dependencies,
// services, or components that could require it
// note: the “ value is swapped for the actual environment variable in /lib/cmd/compile/scripts.js

window.process = window.process || ;
window.process.env = window.process.env || ;

if (!window.process.env.NODE_ENV)
window.process.env.NODE_ENV = ”;
// note: legacy controllers that require legacy services (e.g. dollar-slice) must
// wait for DOMContentLoaded to initialize themselves, as the files themselves must be mounted first

// ]]