A simple link hub, to display and search links. Allows easy branding, runs with the least privileges and is simple to use.
- statically generated site
- single static-compiled go binary
- runs as non-root by default
- integrate any search engine
- simple and intuitive design
- integrated search
- inlines external images on start up
- dependency free
- fully accessible for blind people & screen reader users
- any container platform or supported base system
The container generates the static HTML page on startup, keeps it in memory and serves it using a go webserver.
You can simply run it using e.g. docker with docker-compose:
version: "3.5"
services:
yal:
image: timoreymann/yal:latest # check for version to use if you would like to pin it
restart: always
ports:
- <public-port>:2024
volumes:
- ./config:/app/config
- ./icons:/app/icons # optional in case you want to use local icons
- ./images:/app/images # contains favicon etc.
environment:
# Port to listen
YAL_PORT: 2024
# page title for html
YAL_PAGE_TITLE: My link hub
# Path to config files
YAL_CONFIG_FOLDER: /app/config
# Path to images, see below for available ones
YAL_IMAGES_FOLDER: /app/images
# Omit file extension as it will be picked up by name automatically
# each of the entries is searched like ${YAL_IMAGES_FOLDER}/<icon>{png,jpg,jpeg,svg}
# if that does not succeed, an attempt is made to load the path as is and if
# there is no such file it tries to load it as an URL.
YAL_MASCOT: mascot # the mascot to display on the left
YAL_LOGO: logo # logo to display on the right
YAL_BACKGROUND: background # background image for page
YAL_FAVICON: favicon # favicon to serveSpecifying all env vars manually (if you want to customize them) and keeping the directory structure you can also just generate a static HTML page.
- Download the latest release for your platform
./yal --render --output file.html- Serve
file.htmlusing any static file server
Instead of the regular image use the CI version: timoreymann/yal:ci or for a versioned
tag timoreymann/yal:{version}-ci.
version: 2.1
# Define the jobs we want to run for this project
jobs:
build-page:
docker:
- image: timoreymann/yal:ci
steps:
# Checkout repo with yal config and assets
- checkout
- run:
name: Generate page with yal
command: yal
# Upload the artifact html somewhere
- store_artifacts:
path: templated.html
workflows:
build_link_hub:
jobs:
- build-pagestages:
- build
build-page:
stage: build
image:
name: timoreymann/yal:ci
entrypoint: [""]
script:
# Build page with yal config and assets from project
- yal
artifacts:
paths:
- templated.htmlTHe container comes with some demo data by default, while the CLI will fail with an error when you attempt to render the page without the corresponding files present.
| Environment variable | Flag | Default | Description |
|---|---|---|---|
| YAL_BACKGROUND | --background | background |
Basename of a file without extension (searched in images-folder) or an HTTP url of the image to be used as a background image |
| YAL_BACKGROUND_FILTER | --background-filter | blur(5px) brightness(0.9) |
CSS Filter to apply to the background image. See MDN docs for more information and examples for the filter CSS function for more information |
| YAL_CONFIG_FOLDER | --config-folder | config |
Relative or absolute path where the configuration files reside |
| YAL_FAVICON | --favicon | favicon |
Basename of a file without extension (searched in images-folder) or an HTTP url of the image to be used as favicon for the page |
| YAL_IMAGES_FOLDER | --images-folder | images |
Relative or absolute path where the images reside |
| YAL_LOGO | --logo | logo |
Basename of a file without extension (searched in images-folder) or an HTTP url of the image to be used as a logo on the right |
| YAL_MASCOT | --mascot | mascot |
Basename of a file without extension (searched in images-folder) or an HTTP url of the image to be used as a logo on the left |
| YAL_OUTPUT | --output | templated.html |
File to render to if -render is specified, use - to render to stdout |
| YAL_PAGE_TITLE | --page-title | LinkHub - The place where it just clicks. |
Title of the HTML page generated |
| YAL_PORT | --port | 2024 |
The HTTP port of the server when run with serve (default) |
| YAL_RENDER | --render | false |
Render to output and exit |
| YAL_SERVE | --serve | false |
Render and Serve on HTTP |
| YAL_TEMPLATE_FILE | --template-file | builtin |
Template file to Render, builtin uses the bundled one with yal |
Besides the env vars, there are two config files to maintain:
Configures the search engines for search box to display as last elements
[
{
"title": "Name",
"urlPrefix": "https://my.search?text=<here search term will be appended>"
}
]Configures the links to display.
[
{
"title": "<Title of the section>",
"entries": [
{
"text": "<Display text for the link>",
"link": "<link>",
"description": "<short description for search and hover tooltip>",
"icon": "<url or local path, can be relative; needs to be accessible by container and will be inlined on start up>"
}
]
}
]There are a tons of landing pages out there, each has a unique set of features.
Some simply provide a lot of stuff that are not necessary for a simple link hub. Others look too cluttered or are not intuitive to use.
This project aims to fill the gap and provide a link hub with search that is easy to brand and use. Nothing more or less.
I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the configuration
- Submitting a fix
- Proposing new features
- Becoming a maintainer
To get started please read the Contribution Guidelines.
- GNU make
- Docker
- pre-commit
- Go 1.21
make testmake build