Minimal example custom route plugin

Viewed 186

Hi,

Thanks for the great product.

But after many attempts, reading the docs, I conclude that I really need a tutorial on how to make a custom plugin, concretely:

  1. Make a minimal example custom Route plugin (standard UI)
  2. Cook it in a docker image
  3. Test it out

I've tried the approach below, but it won't work and I can't figure it out yet. Your documentation is elaborate on using official plugins, but the real value is in allowing people to make their own plugins.

Can you help me out? I've lined out my approach below, hope it's clear.


Public github page:
github.com/wgeul/hello-route

Folder structure in project:

hello-route/
  go.mod
  ui/
    src/
      plugins/
        hello-route/
          info.yaml
          index.ts
          Component.tsx
          i18n/
            en_US.yaml
            index.ts
Dockerfile

hello-route/go.mod:

module github.com/wgeul/hello-route

go 1.23

hello-route/ui/src/plugin/hello-route/info.yaml:

slug_name: hello-route
type: route
route: /hello
version: 0.0.1
author: you

hello-route/ui/src/plugin/hello-route/index.ts:

import i18nConfig from './i18n';
import Component from './Component';
import info from './info.yaml';

export default {
    info: {
        slug_name: info.slug_name,
        type: info.type,
        route: info.route,
    },
    i18nConfig,
    component: Component,
};

hello-route/ui/src/plugin/hello-route/Component.tsx:

import type { FC } from 'react';

const Component: FC = () => (
    <div className="container mx-auto max-w-2xl p-6">
        <h1 className="text-2xl font-bold mb-2">Hello from a Route Plugin šŸ‘‹</h1>
        <p className="opacity-80">Served at <code>/hello</code> by the plugin.</p>
    </div>
);

export default Component;

hello-route/ui/src/plugin/hello-route/i18n/en_US.yaml:

name: Hello Route
description: A minimal route plugin that renders /hello

hello-route/ui/src/plugin/hello-route/i18n/index.ts:

import en_US from './en_US.yaml';
export default { en_US };

Dockerfile:

# 1) Pull the official Answer image for the CLI + entrypoint files
FROM apache/answer AS answer-builder

# 2) Builder with the right toolchain
#    Answer needs Go >= 1.23, Node >= 20, pnpm >= 9
#    https://github.com/apache/answer (README prerequisites)
FROM golang:1.23-alpine AS golang-builder
COPY --from=answer-builder /usr/bin/answer /usr/bin/answer
RUN apk --no-cache add build-base git bash curl nodejs npm \
    && npm i -g pnpm@9

# 3) Copy your route plugin repo
WORKDIR /work
COPY hello-route /work/hello-route

# (Optional but safe): align plugin go.mod to 1.23 too
# RUN sed -i 's/^go .*/go 1.23/' /work/hello-route/go.mod

# 4) Build Answer with the local plugin (note the @v0.0.1=/path)
RUN answer build \
    --with github.com/wgeul/[email protected]=/work/hello-route \
    --output /usr/bin/new_answer

# 5) Final runtime image
FROM alpine
ARG TIMEZONE
ENV TIMEZONE=${TIMEZONE:-"Etc/UTC"}
RUN apk add --no-cache bash ca-certificates curl dumb-init gettext openssh sqlite gnupg tzdata \
    && ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
    && echo "${TIMEZONE}" > /etc/timezone
COPY --from=golang-builder   /usr/bin/new_answer /usr/bin/answer
COPY --from=answer-builder   /data /data
COPY --from=answer-builder   /entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh
VOLUME ["/data"]
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
1 Answers

Hi @Willem,

Great question! I've recently optimized the official scaffolding tool to make creating Answer plugins much easier. Let me show you how to create a minimal Route plugin with the improved tool.

The optimized scaffolding tool now handles everything automatically, making plugin creation much simpler:

# Install the tool (package name is create-answer-plugin)
npm install -g create-answer-plugin@beta
# or use npx (recommended)
npx create-answer-plugin@beta create hello-route

Note: The package name is create-answer-plugin, but you can use either create-answer-plugin or answer-plugin as the command (both work!).

The tool automatically:

  • āœ… Generates all required files with correct structure
  • āœ… Creates the Go wrapper file (required for registration)
  • āœ… Sets up proper go.mod with all dependencies
  • āœ… Generates i18n files with correct structure
  • āœ… Installs the plugin to your Answer project
  • āœ… Handles all the boilerplate code

This makes creating plugins much faster and eliminates common setup errors!

Installation Steps

Using the scaffolding tool is the recommended and easiest way:

# 1. Create the plugin (both commands work)
npx create-answer-plugin@beta create hello-route
# or: npx answer-plugin@beta create hello-route
# Select: Standard UI Plugin → Route
# Enter route path: /hello

# 2. Navigate to your Answer project
cd /path/to/answer

# 3. Install the plugin (automatically handles registration)
npx create-answer-plugin@beta install hello-route
# or: npx answer-plugin@beta install hello-route

# The install command automatically:
# - Adds plugin import to main.go
# - Adds replace directive to go.mod
# - Runs go mod tidy
# - Merges i18n resources

# 4. Install frontend dependencies and build
cd /path/to/answer/ui
pnpm pre-install
pnpm build

# 5. Build and run Answer
cd /path/to/answer
go run ./cmd/answer/main.go run -C ./answer-data

The plugin will be available at http://localhost:80/hello (or your configured port).