New character reference page for all my characters, based on 11ty and WebC https://ref.sebin-nyshkim.net/
Find a file
Sebin Nyshkim c096fc1dfd
feat: add home button to navigate back to character select
When deep-linking character pages there's no way for a visitor to know there's other characters as well
2025-08-02 23:02:25 +02:00
src feat: add home button to navigate back to character select 2025-08-02 23:02:25 +02:00
.gitignore
.prettierrc
eleventy.config.js style: 🎨 extract map function for better readability 2025-07-18 11:30:07 +02:00
package-lock.json
package.json
README.md

Character Ref Pages

Reference pages for all of the OCs (original characters) of Sebin Nyshkim.

These reference pages are intended to provide artists with extensive info and reference material for commissions.

Technologies

This project is built using 11ty with WebC. It builds a (mostly) static website that's easy to serve with any webserver, no backend necessary.

WebC allows for easily composable components that get compiled to standard HTML elements (with the option to have them compiled to native web components).

For normal content pages, Markdown is used. Since Markdown allows the inclusion of HTML in md files, this is used to include WebC components in content pages.

Get up and running

After cloning the repo, install the required NPM dependencies:

npm install

11ty comes with an integrated web server with hot reloading for local development. To start it, simply:

npm run start

Note

There currently seems to be an issue with the way hot reloading and transformation works when using WebC and Markdown together in the same project. If the page doesn't update as expected after having made changes, restart the local dev server.

To build the project, simply:

npm run build

This puts the finished page into the public directory. All files can be deployed to a webserver as-is.

Project structure

Per the eleventy.config.js file, all input files are located in the src directory. All other directories defined in the config object at the end of the config file are relative to the src directory.

Layouts

Pages are mostly comprised of two layouts: base and character. The base layout provides the basic HTML structure with the <head> and <body> elements. The character pages all use the character layout.

When adding a new character, make sure to add a corresponding directory data file with the same name as the character, i.e. [character]/[character].11tydata.json with the following content:

{
  "layout": "character.webc"
}

Components

WebC components in 11ty encapsulate HTML, CSS and JavaScript in a single file (similar to how Vue.js SFCs work). This greatly helps maintainability and separation of concerns.

The modularized nature of WebC allows for a composable structure of 11ty websites, with their ability to use the <slot> element, which this project makes extensive use of. Together with special WebC extensions, like webc:if and webc:for, markup can be dynamically generated. Additionally, <script webc:setup> allows for pre-processing of data passed to a component before transformation into HTML.

WebC also enables bundling of CSS and JS, causing only the relevant parts of it to be loaded for any given page to reduce load times.

CSS can be scoped to a WebC component with <style webc:scoped> attribute. This gives the component a randomized class name to prevent style collisions across components. Additionally, if a name is passed to webc:scoped WebC will instead use that as the class name instead of a randomized string. Using the CSS :host selector binds styles to either the randomized or chosen class name. So this:

<style webc:scoped="my-component">
  :host {
    background-color: rebeccapurple;
    color: white;
  }
</style>

Will transform into:

.my-component {
  background-color: rebeccapurple;
  color: white;
}

Warning

Style encapsulation is very strict! In order to account for selector changes outside of the component, the nesting operator & should be used, as it will be kept as-is and the selector logic will work as expected.

Character pages

The project makes heavy use of 11ty's data cascade. For this reason, it is essential to keep data about the characters in their respective directories harmonized, i.e. keeping property, variable and function names in the [character].11tydata.js files the same across characters. This way, pulling in data into components and pages stays relatively easy and straight-forward.

Note

You might be wondering why there's both a json and js 11ty data file in each of the character's directories. This is because json data files cannot hold functions to provide processed data to components in the data cascade that lends itself better to consumption by components. The data defined in json files is also not accessible to functions in js files. In order to keep page configuration, character data and content separate, this approach was chosen.

Image processing

Images are processed by the 11ty image plugin. It comes with its own component <eleventy-image>. Images passed to it will get processed into different formats according to the options in eleventy.config.js, making the use of responsive images across the site significantly easier and more pleasant. File names in the img sub-directory follow the same structure as the character pages: each character has their own sub-directory according to their first name. At minimum, there needs to exist a avatar.png file for display on the front page and in the sidebar on the character page. Any other images can be added as needed.

Note

This site allows characters to have both SFW and NSFW versions of reference images. Setting the nsfw attribute on a <ref-img> component to true causes the component to attempt to load an additional image with the same base name as src with an additional suffix of -nsfw at the and of the file name.