Developer docs

Publish menus anywhere that can render HTML.

MenuPublish exposes each approved menu as a public, cacheable HTML fragment with schema.org markup. Use the WordPress plugin, iframe embed, or fetch the fragment server-side in your own app.

Endpoint

Public GET render URL. No API key is required.

Output

HTML fragment, accessible markup, and schema.org Menu JSON-LD.

Cache

Cached for fast reads and revalidated when a menu is published.

Recommended integration path

For SEO, prefer server-rendered HTML whenever the platform allows it. The official WordPress plugin and direct server-side fetch both put the menu markup into the page response, so crawlers and screen readers see the menu as part of the restaurant site.

The JavaScript embed is the right default for hosted builders that do not allow server-side code. It feels more native than an iframe and is easier to theme, but crawler treatment depends on client-side rendering. The iframe remains the simplest fallback for platforms with limited custom-code support.

Render endpoint

GEThttps://menupublish.com/render/{accountSlug}/{menuSlug}

Replace accountSlug with the restaurant account slug and menuSlug with the target menu slug, usually something like dinner, brunch, or main. Both values are shown on the Integrations card in the MenuPublish dashboard.

A successful request returns an HTML fragment, not a full document. That makes it safe to insert inside an existing page layout. Missing accounts, inactive menus, or unpublished menus return 404.

Multi-location accounts

Accounts with more than one location address each menu through a three-segment URL that includes the location slug:

GEThttps://menupublish.com/render/{accountSlug}/{siteSlug}/{menuSlug}

The same form works for single-location accounts (the location slug is usually main). The two-segment URL above is supported as a convenience for accounts that have not yet added a second location.

WordPress

The WordPress plugin is the recommended integration for WordPress sites. It fetches the public render endpoint server-side, caches the last successful response, and receives publish webhooks so menu updates appear quickly.

[menupublish menu="dinner"]

Use the MenuPublish block for Gutenberg pages, or the shortcode above in any post, page, or template area that supports shortcodes.

JavaScript embed

The JavaScript embed is the preferred no-backend option for Squarespace, Wix, Webflow, and other hosted builders. It injects the same rendered menu HTML directly into the page and allows the menu to inherit the surrounding site styles.

<div
  data-menupublish-menu
  data-account="mariposa"
  data-menu="dinner"
></div>
<script
  async
  src="https://menupublish.com/embed.js"
></script>

Add a data-site attribute when the account has more than one location:

<div
  data-menupublish-menu
  data-account="mariposa"
  data-site="uptown"
  data-menu="brunch"
></div>
<script
  async
  src="https://menupublish.com/embed.js"
></script>

The script also exposes window.MenuPublish.refresh() for manually re-fetching after a publish, and emits a menupublish:loaded DOM event on the target element when content is in place.

Iframe fallback

Use the iframe when a site builder strips scripts or when you need the fastest possible embed path. It is reliable, but the menu lives in a separate document, so it is not the preferred SEO integration.

<iframe
  src="https://menupublish.com/render/mariposa/dinner"
  style="width:100%;border:0;min-height:600px"
  loading="lazy"
  title="Menu"
></iframe>

Server-side fetch

Custom sites can fetch the fragment during server rendering and inline it into their own route. Keep a short revalidation window so your page benefits from local caching without staying stale for long.

export async function RestaurantMenu() {
  const response = await fetch(
    "https://menupublish.com/render/mariposa/dinner",
    { next: { revalidate: 300 } }
  );

  if (!response.ok) return null;

  const html = await response.text();
  return <section dangerouslySetInnerHTML={{ __html: html }} />;
}
The render endpoint is intentionally public because search engines and website frontends need to read it. The editable source menu still lives behind the MenuPublish dashboard.

Styling

The rendered menu ships with accessible defaults and can be themed with CSS custom properties from the host page.

.menupublish-menu {
  --menupublish-bg: #fffaf2;
  --menupublish-text: #211f1c;
  --menupublish-muted: #6f6960;
  --menupublish-accent: #b94224;
  --menupublish-font-body: inherit;
  --menupublish-font-heading: "Instrument Serif", Georgia, serif;
}
VariableControls
--menupublish-bgMenu background color.
--menupublish-textMain text, item names, and section headings.
--menupublish-mutedDescriptions, helper text, and secondary details.
--menupublish-accentRules, labels, and small highlight treatments.
--menupublish-font-bodyBody font for menu descriptions and details.
--menupublish-font-headingHeading font for menu and section names.

Caching and updates

MenuPublish caches render responses by account slug and menu slug. When a user publishes a new menu version, the render cache is revalidated immediately. Connected WordPress sites also receive a signed cache-invalidation webhook.

If you build your own integration, treat the endpoint as cacheable content and retry later on transient failures. WordPress sites using the official plugin automatically serve the last-known-good menu if MenuPublish is temporarily unreachable.

Need a different surface?

The public surface today is rendered HTML. If you need structured JSON or a platform-specific integration, email [email protected] with the site platform and the menu destination you need.