Things to Do

Location-based content pages with structured attraction data-list, fetch, paginate, and iterate the same way as posts.

Methods

nf.thingsToDo.list(params?)     // List pages (paginated)
nf.thingsToDo.get(slug, opts?) // Single page with attractions
nf.thingsToDo.all(params?)     // ALL pages (auto-paginated)
nf.thingsToDo.slugs()          // All slugs
nf.thingsToDo.iter(params?)    // Async iterator over all pages

Params & options

List params: page, limit, city, state, sort

Get options: format ("json" | "html"). With "html", the response includes page.contentHtml plus top-level contentStyles and layoutHints for styling and layout guidance.

SEO: List items and full pages include noIndex (boolean). When true, tell crawlers not to index the URL.

Maps & embeds

Each attraction can include:

  • mapEmbedSrc - HTTPS URL suitable for an iframe src attribute pointing at attraction.mapEmbedSrc. Prefer this over putting raw embed HTML in src.
  • mapEmbed - Full iframe HTML from NexoFlow. Render with dangerouslySetInnerHTML (or your framework’s equivalent), not as an iframe src.
  • mapLink - Opens the place in Google Maps in a new tab.

mapEmbedSrc may be null if only a short link was stored and a synchronous embed URL could not be derived-fall back to mapEmbed or mapLink.

SEO / App Router metadata

page.tsx
// app/things-to-do/[slug]/page.tsx
import type { Metadata } from "next"
import { NexoFlow } from "nexoflow-sdk"

const nf = new NexoFlow({ apiKey: process.env.NEXOFLOW_API_KEY! })

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string }>
}): Promise<Metadata> {
  const { slug } = await params
  const { data } = await nf.thingsToDo.get(slug)
  const page = data.page
  return {
    title: page.metaTitle || page.pageTitle,
    description: page.metaDescription ?? undefined,
    ...(page.noIndex ? { robots: { index: false, follow: false } } : {}),
  }
}