Theme

Configuration

TypeScript
import { defineConfig } from 'ezal';
import { theme } from 'ezal-theme-example';
import { Temporal } from '@js-temporal/polyfill';

export default defineConfig({
  // Other configurations are ignored
	theme: await theme({
		favicon: ['/favicon.svg'],
		nav: [
			{ name: 'Home', link: '/' },
			{ name: 'Archive', link: '/archive/' },
			{ name: 'Links', link: '/links/' },
			{ name: 'About', link: '/about/' },
		],
		since: Temporal.ZonedDateTime.from({
			year: 2025,
			month: 11,
			day: 8,
			hour: 21,
			minute: 40,
			second: 0,
			timeZone: 'Asia/Shanghai',
		}),
		contact: [
			{
				color: '#444',
				icon: 'github',
				name: 'Github',
				url: 'https://github.com/JonnyJong/ezal',
			},
			{
				color: '#d67c00',
				icon: 'rss',
				name: 'Atom',
				url: '/atom.xml',
			},
		],
		links: [
			{
				title: 'Links',
				description: 'Blog example',
				items: [
					{
						name: `Jonny's Blog`,
						description: 'Welcome to my little site',
						link: 'https://jonnys.top/',
						avatar: 'https://jonnys.top/img/avatar.svg',
						color: '#00AA00',
					},
				],
			},
		],
		inject: '<link rel="stylesheet" href="/icon/index.css">',
		home: {
			slogan: 'Welcome!👋<br>Here is the demo site of ezal blog framework.',
		},
	}),
});

Features

Implemented based on pagefind, it indexes all articles by default and does not index regular pages.
To disable indexing for a specific article, add index: false to its frontmatter;
To enable indexing for a regular page, add index: true to its frontmatter.

This feature will generate the following files:

RSS, Atom

Implemented based on feed, it includes all articles and categories.

This feature will generate the following files:

Sitemap

Implemented based on sitemap, it indexes all articles and the homepage by default, and does not index regular pages.
To disable indexing for a specific article, add sitemap: false to its frontmatter;
To enable indexing for a regular page, add sitemap: true to its frontmatter.

This feature will generate the following files:

IndexNow

The theme integrates IndexNow, which can be used after configuring the key.

It indexes all articles and the homepage by default, and does not index regular pages.
To disable indexing for a specific article, add robots: false to its frontmatter;
To enable indexing for a regular page, add robots: true to its frontmatter.

TypeScript
import { defineConfig } from 'ezal';
import { theme } from 'ezal-theme-example';

export default defineConfig({
  // Other configurations are ignored
	theme: await theme({
    indexNow: {
      bing: 'your_bing_key', // Bing IndexNow key
      yandex: 'your_yandex_key', // Yandex IndexNow key
    },
	}),
});

Waline

The theme integrates Waline, which can be enabled after adding the server URL configuration:

TypeScript
import { defineConfig } from 'ezal';
import { theme } from 'ezal-theme-example';

export default defineConfig({
  // Other configurations are ignored
	theme: await theme({
    waline: {
      serverUrl: 'https://example.com',
      visitor: true, // Enable visitor count
      commentCount: true, // Enable comment count display
      pageview: true, // Enable page view count
      emoji: ['https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/weibo'], // Custom emoji set
      reaction: ['https://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/60/2018new_grinninga_org.png'], // Reaction emoji
    },
	}),
});

Image Optimization

The theme supports automatic image optimization, automatically converting images to multiple formats for optimal performance.

Supported input formats:

Default optimization rules:

TypeScript
import { defineConfig } from 'ezal';
import { theme } from 'ezal-theme-example';

export default defineConfig({
  theme: await theme({
    imageCache: {
      // Image metadata cache path
      metadata: './image-metadata.sqlite',
      // Optimized image cache path
      optimized: './cache',
    }
  }),
});

Detailed Theme Configuration Options

TypeScript
nav: [
  { name: 'Home', link: '/' },
  { name: 'Archive', link: '/archive/' },
  { name: 'Links', link: '/links/' },
  { name: 'About', link: '/about/' },
]

Color Configuration

TypeScript
color: {
  light: '#006000', // Light theme color
  dark: '#00BB00',  // Dark theme color
}

Markdown Options

TypeScript
markdown: {
  lineBreak: 'common-mark', // 'common-mark' | 'soft'
  codeBlockTheme: {
    light: 'light-plus',     // Light code theme
    dark: 'dark-plus'        // Dark code theme
  }
}

Homepage Settings

TypeScript
home: {
  articlesPrePage: 10,       // Number of articles per page
  logo: {
    viewBox: '0 0 100 100',  // SVG logo's viewBox
    g: '<path d="..."/>',    // SVG logo's path definition,
  },
  slogan: 'Welcome to my blog', // Homepage slogan
}

You can customize the styles enabled for the links page:

TypeScript
linkPageStyles: [
  'image',   // Enable image style
  'table',   // Enable table style
  'heading', // Enable heading style
  'list',    // Enable list style
  'footnote',// Enable footnote style
  'tabs',    // Enable tab style
  'note',    // Enable note style
  'fold',    // Enable fold style
  'kbd',     // Enable keyboard label style
]

CDN Configuration

You can customize the CDN URLs for external resources:

TypeScript
cdn: {
  katex: 'https://example.com/katex.min.css',     // KaTeX stylesheet
  walineCSS: 'https://example.com/waline.css',   // Waline stylesheet
  walineJS: 'https://example.com/waline.js',     // Waline script file,
}

Custom HTML Injection

You can inject custom content into the <head> of the page:

TypeScript
inject: '<link rel="stylesheet" href="/icon/index.css">'

Page Types

The theme supports the following page types: