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 pagesParams & 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
srcattribute pointing atattraction.mapEmbedSrc. Prefer this over putting raw embed HTML insrc. - mapEmbed - Full iframe HTML from NexoFlow. Render with
dangerouslySetInnerHTML(or your framework’s equivalent), not as an iframesrc. - 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 } } : {}),
}
}