gnoweb

package
v0.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2025 License: UNKNOWN not legal advice Imports: 0 Imported by: 0

README

gnoweb

gnoweb is a universal web frontend for the gno.land blockchain.

This README provides instructions on how to set up and run gnoweb for development purposes.

Prerequisites

Before you begin, ensure you have the following software installed on your machine:

  • Node.js: Required for running JavaScript and CSS build tools.
  • Go: Required for building gnoweb

Development

In order to run gnoweb in developement mode ensure that a local gnoland node is up and running. For development purposes, it's recommended to use gnodev as the development node.

You can launch a fresh node using:

make node-start # or use `gnodev -no-web` directly

Then use the following command on another terminal to start the development environment, which runs multiple tools in parallel:

make dev

This will:

  • Start a gnoweb server in development mode and watch for any Go files change (listening on localhost).
  • Enable Tailwind CSS in watch mode to automatically compile CSS changes.
  • Use esbuild in watch mode to automatically transpile and bundle TypeScript changes.
Custom remote

By default, make dev uses a local node. However, you can specify a custom target using the DEV_REMOTE environment variable (and optionally set CHAIN_ID variable).

For example, to use gno.land as the target, run:

DEV_REMOTE=https://rpc.gno.land make dev
Static Assets in Development

When running in development mode (with make dev), static assets are not embedded in the binary. Instead, they are served from a directory specified by the GNOWEB_ASSETDIR environment variable or the AssetDir preprocessor variable (set via -ldflags).

Editor Integration

We use Biome for frontend linting and formatting.

You can either install the appropriate Biome extension for your editor by following the official guide. Or simply run make lint or make fmt (that will automatically run biome under the hood).

Generate

To generate the public assets for the project, including static assets (fonts, CSS and JavaScript... files), run the following command. This should be used while editing CSS, JS, or any asset files:

make generate

Documentation

Index

Constants

View Source
const ReadmeFileName = "README.md"

Variables

View Source
var (
	ErrClientPackageNotFound   = errors.New("package not found")
	ErrClientFileNotFound      = errors.New("file not found")
	ErrClientRenderNotDeclared = errors.New("render function not declared")
	ErrClientBadRequest        = errors.New("bad request")
	ErrClientResponse          = errors.New("node response error")
	ErrClientFile              = errors.New("unknown or invalid filename for path")
)
View Source
var DefaultAliases = map[string]AliasTarget{
	"/":           {"/r/gnoland/home", GnowebPath},
	"/about":      {"/r/gnoland/pages:p/about", GnowebPath},
	"/gnolang":    {"/r/gnoland/pages:p/gnolang", GnowebPath},
	"/ecosystem":  {"/r/gnoland/pages:p/ecosystem", GnowebPath},
	"/start":      {"/r/gnoland/pages:p/start", GnowebPath},
	"/license":    {"/r/gnoland/pages:p/license", GnowebPath},
	"/contribute": {"/r/gnoland/pages:p/contribute", GnowebPath},
	"/links":      {"/r/gnoland/pages:p/links", GnowebPath},
	"/events":     {"/r/gnoland/events", GnowebPath},
	"/partners":   {"/r/gnoland/pages:p/partners", GnowebPath},
	"/docs":       {"/u/docs", GnowebPath},
}
View Source
var DefaultCacheAssetsHandler = func(next http.Handler) http.Handler {
	return CacheHandler(assetsHash, next)
}
View Source
var DefaultChromaRenderStyle = styles.Get("friendly")
View Source
var Redirects = map[string]string{
	"/r/demo/boards:gnolang/6": "/r/demo/boards:gnolang/3",
	"/blog":                    "/r/gnoland/blog",
	"/gor":                     "/contribute",
	"/game-of-realms":          "/contribute",
	"/grants":                  "/partners",
	"/language":                "/gnolang",
	"/getting-started":         "/start",
}

Redirects is a map of gnoweb paths that are redirected using RedirectMiddleware.

Functions

func AssetHandler

func AssetHandler() http.Handler

AssetHandler returns an http.Handler to serve static assets from the embedded filesystem. Assets are always served from the embedded /public directory.

func CacheHandler

func CacheHandler(hash string, next http.Handler) http.Handler

CacheHandler adds ETag and Cache-Control headers to all asset responses for caching.

func CreateUsernameFromBech32

func CreateUsernameFromBech32(username string) string

TODO: Check username from r/sys/users in addition to bech32 address test (username + gno address to be used) CreateUsernameFromBech32 creates a shortened version of the username if it's a valid bech32 address.

func GetClientErrorStatusPage

func GetClientErrorStatusPage(_ *weburl.GnoURL, err error) (int, *components.View)

func NewDefaultChromaOptions

func NewDefaultChromaOptions() []chromahtml.Option

NewDefaultChromaOptions returns the default Chroma options for syntax highlighting.

func NewDefaultGoldmarkOptions

func NewDefaultGoldmarkOptions() []goldmark.Option

NewDefaultGoldmarkOptions returns the default Goldmark options for Markdown rendering.

func NewRouter

func NewRouter(logger *slog.Logger, cfg *AppConfig) (http.Handler, error)

NewRouter initializes the gnoweb router with the specified logger and configuration. It sets up all routes, static asset handling, and middleware.

func NoCacheHandler

func NoCacheHandler(next http.Handler) http.Handler

NoCacheHandler always invalidates cache for all responses.

func RedirectMiddleware

func RedirectMiddleware(next http.Handler, analytics bool) http.Handler

RedirectMiddleware redirects all incoming requests whose path matches any of the Redirects to the corresponding URL, and renders a redirect view.

Types

type AliasKind

type AliasKind int
const (
	GnowebPath AliasKind = iota
	StaticMarkdown
)

type AliasTarget

type AliasTarget struct {
	Value string
	Kind  AliasKind
}

type AppConfig

type AppConfig struct {
	// UnsafeHTML, if enabled, allows to use HTML in the markdown.
	UnsafeHTML bool
	// Analytics enables SimpleAnalytics.
	Analytics bool
	// NodeRemote is the remote address of the gno.land node.
	NodeRemote string
	// RemoteHelp is the remote of the gno.land node, as used in the help page.
	RemoteHelp string
	// AssetsPath is the base path to the gnoweb assets.
	AssetsPath string
	// NoAssetsCache disables assets caching.
	NoAssetsCache bool
	// ChainID is the chain id, used for constructing the help page.
	ChainID string
	// FaucetURL, if specified, will be the URL to which `/faucet` redirects.
	FaucetURL string
	// Domain is the domain used by the node.
	Domain string
	// Aliases is a map of aliases pointing to another path or a static file.
	Aliases map[string]AliasTarget
	// RenderConfig defines the default configuration for rendering realms and source files.
	RenderConfig RenderConfig
}

AppConfig contains configuration for gnoweb.

func NewDefaultAppConfig

func NewDefaultAppConfig() *AppConfig

NewDefaultAppConfig returns a new default AppConfig. The default sets 127.0.0.1:26657 as the remote node, "dev" as the chain ID, and sets up assets to be served on /public/.

type ClientAdapter

type ClientAdapter interface {
	// Realm fetch the content of a realm from a given path and
	// return the data.
	Realm(path, args string) ([]byte, error) // raw Render() bytes

	// File fetche the source file from a given
	// package path and filename.
	File(path, filename string) ([]byte, FileMeta, error)

	// Sources lists all source files available in a specified
	// package path.
	ListFiles(path string) ([]string, error)

	// QueryPath list any path given the specified prefix
	ListPaths(prefix string, limit int) ([]string, error)

	// Doc retrieves the JSON doc suitable for printing from a
	// specified package path.
	Doc(path string) (*doc.JSONDocumentation, error)
}

func NewRPCClientAdapter

func NewRPCClientAdapter(logger *slog.Logger, cli *client.RPCClient, domain string) ClientAdapter

NewHTMLClient creates a new instance of WebClient. It requires a configured logger and WebClientConfig.

type FileMeta

type FileMeta struct {
	Lines  int
	SizeKB float64
}

type HTMLRenderer

type HTMLRenderer struct {
	// contains filtered or unexported fields
}

HTMLRenderer implements the Renderer interface for HTML output.

func NewHTMLRenderer

func NewHTMLRenderer(logger *slog.Logger, cfg RenderConfig) *HTMLRenderer

func (*HTMLRenderer) RenderRealm

func (r *HTMLRenderer) RenderRealm(w io.Writer, u *weburl.GnoURL, src []byte) (md.Toc, error)

RenderRealm renders a realm to HTML and returns a table of contents.

func (*HTMLRenderer) RenderSource

func (r *HTMLRenderer) RenderSource(w io.Writer, name string, src []byte) error

RenderSource renders a source file into HTML with syntax highlighting based on its extension.

func (*HTMLRenderer) WriteChromaCSS

func (r *HTMLRenderer) WriteChromaCSS(w io.Writer) error

WriteChromaCSS writes the CSS for syntax highlighting to the provided writer.

type HTTPHandler

type HTTPHandler struct {
	Logger   *slog.Logger
	Static   StaticMetadata
	Client   ClientAdapter
	Renderer Renderer
	Aliases  map[string]AliasTarget
}

HTTPHandler processes HTTP requests for gnoweb.

func NewHTTPHandler

func NewHTTPHandler(logger *slog.Logger, cfg *HTTPHandlerConfig) (*HTTPHandler, error)

NewHTTPHandler creates a new HTTPHandler.

func (*HTTPHandler) Get

func (h *HTTPHandler) Get(w http.ResponseWriter, r *http.Request)

Get processes a GET HTTP request and renders the appropriate page.

func (*HTTPHandler) GetDirectoryView

func (h *HTTPHandler) GetDirectoryView(gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)

GetDirectoryView renders the directory view for a package, showing available files.

func (*HTTPHandler) GetHelpView

func (h *HTTPHandler) GetHelpView(gnourl *weburl.GnoURL) (int, *components.View)

func (*HTTPHandler) GetMarkdownView

func (h *HTTPHandler) GetMarkdownView(gnourl *weburl.GnoURL, mdContent string) (int, *components.View)

GetMarkdownView handles rendering of markdown files.

func (*HTTPHandler) GetPackageView

func (h *HTTPHandler) GetPackageView(gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)

GetPackageView handles package pages, including help, source, directory, and user views.

func (*HTTPHandler) GetPathsListView

func (h *HTTPHandler) GetPathsListView(gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)

func (*HTTPHandler) GetRealmView

func (h *HTTPHandler) GetRealmView(gnourl *weburl.GnoURL, indexData *components.IndexData) (int, *components.View)

GetRealmView renders a realm page or returns an error/status if not available.

func (*HTTPHandler) GetSourceDownload

func (h *HTTPHandler) GetSourceDownload(gnourl *weburl.GnoURL, w http.ResponseWriter, r *http.Request)

GetSourceDownload handles downloading a source file as plain text.

func (*HTTPHandler) GetSourceView

func (h *HTTPHandler) GetSourceView(gnourl *weburl.GnoURL) (int, *components.View)

func (*HTTPHandler) GetUserView

func (h *HTTPHandler) GetUserView(gnourl *weburl.GnoURL) (int, *components.View)

GetUserView returns the user profile view for a given GnoURL.

func (*HTTPHandler) Post

func (h *HTTPHandler) Post(w http.ResponseWriter, r *http.Request)

Post processes a POST HTTP request.

func (*HTTPHandler) ServeHTTP

func (h *HTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles HTTP requests and only allows GET requests.

type HTTPHandlerConfig

type HTTPHandlerConfig struct {
	Meta          StaticMetadata
	ClientAdapter ClientAdapter
	Renderer      Renderer
	Aliases       map[string]AliasTarget
}

HTTPHandlerConfig configures an HTTPHandler.

type MockClient

type MockClient struct {
	Packages map[string]*MockPackage // path -> package
}

MockClient is a mock implementation of the ClientAdapter interface for testing.

func NewMockClient

func NewMockClient(pkgs ...*MockPackage) *MockClient

NewMockClient creates a new MockClient from one or more MockPackages.

func (*MockClient) Doc

func (m *MockClient) Doc(path string) (*doc.JSONDocumentation, error)

Doc retrieves the JSON documentation for a specified package path.

func (*MockClient) File

func (m *MockClient) File(pkgPath, fileName string) ([]byte, FileMeta, error)

File fetches the source file from a given package path and filename, returning its content and metadata.

func (*MockClient) ListFiles

func (m *MockClient) ListFiles(path string) ([]string, error)

ListFiles lists all source files available in a specified package path.

func (*MockClient) ListPaths

func (m *MockClient) ListPaths(prefix string, limit int) ([]string, error)

ListPaths lists all package paths that match the specified prefix, up to the given limit.

func (*MockClient) Realm

func (m *MockClient) Realm(path, args string) ([]byte, error)

Realm fetches the content of a realm from a given path and returns the data, or an error if not found or not declared.

type MockPackage

type MockPackage struct {
	Path      string
	Domain    string
	Files     map[string]string // filename -> body
	Functions []*doc.JSONFunc
}

MockPackage represents a mock package with files and function signatures for testing.

type RenderConfig

type RenderConfig struct {
	ChromaStyle     *chroma.Style
	ChromaOptions   []chromahtml.Option
	GoldmarkOptions []goldmark.Option
}

RenderConfig holds configuration for syntax highlighting and Markdown rendering.

func NewDefaultRenderConfig

func NewDefaultRenderConfig() (cfg RenderConfig)

NewDefaultRenderConfig returns a RenderConfig with default styles and options.

type Renderer

type Renderer interface {
	RenderRealm(w io.Writer, u *weburl.GnoURL, src []byte) (md.Toc, error)
	RenderSource(w io.Writer, name string, src []byte) error
}

Renderer defines the interface for rendering realms and source files.

type StaticMetadata

type StaticMetadata struct {
	Domain     string
	AssetsPath string
	ChromaPath string
	RemoteHelp string
	ChainId    string
	Analytics  bool
}

StaticMetadata holds static configuration for a web handler.

Directories

Path Synopsis
cmd
cmd/logname command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL