Skip to Content
DocumentationGetting startedBootstrapping a site

Bootstrapping a site

The bootstrap:site command sets up a fully-wired TwoTaps Next.js site with one command. It clones the official boilerplate, configures your environment, generates TypeScript types from your schemas, and scaffolds stub components for every block — so you can start building instead of plumbing.

Prerequisites

Before running the command you need:

  • Git in your PATH (used to clone the boilerplate)
  • Yarn in your PATH (the boilerplate uses Yarn)
  • A TwoTaps API token — see Generating an API token below
  • Your schema set identifier — either the numeric wrapper ID or the combination of organisation name + schema set name

Generating an API token

  1. Open your TwoTaps administration panel
  2. Navigate to API Token: /administration/api-token?organisationId=YOUR_ORG_ID
  3. Click Generate New Token and copy the result

Store the token securely. Never commit it to source control. Use an environment variable or a secrets manager.

Quick start

Export your API token and run the command:

export TWO_TAPS_API_TOKEN=your_api_token_here npx twotaps bootstrap:site \ --ttGraphqlUrl https://api-lb-prod.twotaps.io/graphql \ --destinationPath ./my-site \ --sitePublicHost https://www.my-site.com \ --orgName "Acme Corp" \ --schemaWrapperName "My Schema Set"

Or, if you know your numeric schema wrapper ID:

export TWO_TAPS_API_TOKEN=your_api_token_here npx twotaps bootstrap:site \ --ttGraphqlUrl https://api-lb-prod.twotaps.io/graphql \ --destinationPath ./my-site \ --sitePublicHost https://www.my-site.com \ --schemaWrapperId 123

Interactive mode

Any omitted required flag triggers an interactive prompt. You can run the command with no flags and answer each question:

export TWO_TAPS_API_TOKEN=your_api_token_here npx twotaps bootstrap:site # TwoTaps GraphQL URL: https://api-lb-prod.twotaps.io/graphql # Schema wrapper ID (optional): # Organisation name (required if wrapper ID not provided): Acme Corp # Schema wrapper name (required if wrapper ID not provided): My Schema Set # Site public host: https://www.acme.com # Site base path (optional): # Destination path: ./acme-site # Boilerplate repository [https://github.com/ltnetwork/twotaps-boilerplate-nextjs.git]:

--orgName / --schemaWrapperName and --schemaWrapperId are mutually exclusive. Provide one set or the other, not both.

Step-by-step walkthrough

Set your API token

The CLI reads authentication credentials from the TWO_TAPS_API_TOKEN environment variable:

export TWO_TAPS_API_TOKEN=your_api_token_here

For persistent use, add this to your shell profile (.zshrc, .bashrc, etc.) or use a .env file in your shell session.

Choose how to identify your schema set

You can identify the target schema set in two ways:

Option A — by schema wrapper ID (fastest)

Find the ID in the TwoTaps admin UI under Schema Sets. The numeric ID appears in the URL: /administration/schema-sets?organisationId=42 → schema wrapper detail page shows its ID.

--schemaWrapperId 123

Option B — by organisation name + schema set name

Use the exact names as they appear in TwoTaps (case-insensitive match):

--orgName "Acme Corp" \ --schemaWrapperName "My Schema Set"

Run the command

npx twotaps bootstrap:site \ --ttGraphqlUrl https://api-lb-prod.twotaps.io/graphql \ --destinationPath ./acme-site \ --sitePublicHost https://www.acme.com \ --orgName "Acme Corp" \ --schemaWrapperName "My Schema Set"

You’ll see progress output as each step completes:

Cloning boilerplate into /path/to/acme-site... Removing sample boilerplate components... Creating .env from .env-example... Running yarn install to setup dependencies... Generating schema types... SDL schema generated at /path/to/acme-site/types.ts, extracting interfaces... Retrieved 12 block schemas from GraphQL API, scaffolding components... Bootstrap complete at /path/to/acme-site Created 12 components

Explore the generated project

After the command completes, your project looks like this:

    • .env
    • .env-example
    • types.ts
        • index.ts
        • HeroBlock.tsx
        • LocationDetails.tsx
        • ContactFormBlock.tsx
        • ...
    • package.json
    • next.config.js

How it works under the hood

1. Boilerplate cloning

The CLI clones the official boilerplate repository (https://github.com/ltnetwork/twotaps-boilerplate-nextjs.git by default).

2. Environment setup

The generated .env file has three values pre-populated from your command flags:

NEXT_PUBLIC_GRAPHQL_URL="https://api-lb-prod.twotaps.io/graphql" NEXT_PUBLIC_HOST="https://www.acme.com" NEXT_PUBLIC_BASE_PATH="" # empty unless --siteBasePath is provided

3. Schema type generation

The CLI calls the TwoTaps schema-builder endpoint (derived from your GraphQL URL) and writes all TypeScript interfaces to types.ts in the project root. Every schema in your schema set gets a corresponding exported interface:

// types.ts (generated — do not edit by hand) export interface HeroBlock { title: string; subtitle?: string; backgroundImage: TTImage; } export interface LocationDetails { city: string; address: string; coords: TTGMBLocation; } export interface ContactFormBlock { formId: number; heading?: string; } // ...

Built-in TwoTaps types (TTImage, TTLink, TTForm, etc.) are excluded from component scaffolding — they are utility types, not page-level block components.

4. Component scaffolding

For each Block-type schema in your schema set, the CLI generates a stub component in src/components/. The component is typed against the matching interface from types.ts:

// src/components/HeroBlock.tsx (generated stub) import type { HeroBlock } from '../../types'; interface HeroBlockProps extends HeroBlock {} export default function HeroBlock(props: HeroBlockProps) { return <div></div>; }

You fill in the rendering logic. The type information is already wired up — TypeScript will catch any property name typos or missing fields immediately.

5. Component wiring (src/components/index.ts)

The final step writes src/components/index.ts with a NEXT_COMPONENTS map that connects schema block names (as returned by TwoTaps) to their corresponding React components:

// src/components/index.ts (generated — regenerate with bootstrap:site) 'use client'; import ContactFormBlock from './ContactFormBlock'; import HeroBlock from './HeroBlock'; import LocationDetails from './LocationDetails'; export const NEXT_COMPONENTS = { contact_form_block: ContactFormBlock, hero_block: HeroBlock, location_details: LocationDetails, };

The boilerplate’s block renderer reads from NEXT_COMPONENTS to resolve the right component for each revision schema block at runtime.

All CLI options

FlagTypeRequiredDescription
--ttGraphqlUrlstringYes (or prompted)TwoTaps GraphQL endpoint, e.g. https://api-lb-prod.twotaps.io/graphql
--destinationPathstringYes (or prompted)Target directory for the new project
--sitePublicHoststringYes (or prompted)Canonical domain, e.g. https://www.my-site.com (sets NEXT_PUBLIC_HOST)
--schemaWrapperIdstringRequired unless orgName/schemaWrapperName is providedNumeric schema set ID — mutually exclusive with --orgName/--schemaWrapperName
--orgNamestringRequired unless schemaWrapperId is providedOrganisation name (case-insensitive)
--schemaWrapperNamestringRequired unless schemaWrapperId is providedSchema set name within the organisation (case-insensitive)
--siteBasePathstringNoSub-path if the site is served under a path prefix, e.g. /us (sets NEXT_PUBLIC_BASE_PATH)
--twoTapsHoststringNoOverride the API host for schema-builder calls. Derived from --ttGraphqlUrl if omitted.
--boilerplateRepostringNoCustom boilerplate Git URL or local path. Defaults to the official TwoTaps Next.js boilerplate.

After bootstrapping

Start the development server

cd acme-site yarn dev

Your site will be available at http://localhost:3000. Pages are fetched from TwoTaps at request time using the GraphQL URL in .env.

Implement your components

Open any generated stub and replace the empty <div> with real markup. The props are fully typed via the interface from types.ts:

// src/components/HeroBlock.tsx import type { HeroBlock } from '../../types'; interface HeroBlockProps extends HeroBlock {} export default function HeroBlock({ title, subtitle, backgroundImage }: HeroBlockProps) { return ( <section style={{ backgroundImage: `url(${backgroundImage.url})` }} aria-label={backgroundImage.alt} > <h1>{title}</h1> {subtitle && <p>{subtitle}</p>} </section> ); }

Regenerating types after schema changes

When you add or update schemas in TwoTaps, regenerate types.ts using the generate:sdl command:

export TWO_TAPS_API_TOKEN=your_api_token_here npx twotaps generate:sdl \ --twoTapsHost https://api-lb-prod.twotaps.io \ --orgName "Acme Corp" \ --schemaWrapperName "My Schema Set"

Re-running bootstrap:site will refuse to overwrite a non-empty destination directory. Use generate:sdl to update types.ts in an existing project.

Using a custom boilerplate

You can point the bootstrapper at your own boilerplate repository:

npx twotaps bootstrap:site \ --ttGraphqlUrl https://api-lb-prod.twotaps.io/graphql \ --destinationPath ./acme-site \ --sitePublicHost https://www.acme.com \ --schemaWrapperId 123 \ --boilerplateRepo https://github.com/your-org/your-boilerplate.git

Your boilerplate must contain:

  • A .env-example file with NEXT_PUBLIC_GRAPHQL_URL, NEXT_PUBLIC_HOST, and NEXT_PUBLIC_BASE_PATH entries
  • A src/components/ directory

Troubleshooting

TWO_TAPS_API_TOKEN environment variable is not set

Export the variable before running the command:

export TWO_TAPS_API_TOKEN=your_api_token_here

Destination directory is not empty

The target directory must not exist (or must be empty). Choose a new path or remove the existing directory:

rm -rf ./acme-site npx twotaps bootstrap:site ...

Organisation not found by name

Double-check that the --orgName value matches the exact name in TwoTaps (the comparison is case-insensitive but the name must be an exact word match). Use --schemaWrapperId if you’re unsure.

GraphQL request failed: 401

Your API token is invalid or expired. Generate a new one from the TwoTaps administration panel.

git: command not found / yarn: command not found

Install the missing tool and ensure it is on your PATH before running bootstrap:site.

Last updated on