Minimal example custom route plugin

Viewed 10

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"]
0 Answers