392 lines
9.9 KiB
Markdown
392 lines
9.9 KiB
Markdown
---
|
|
title: Bulletin
|
|
icon: mingcute:announcement-line
|
|
createTime: 2025/10/08 21:51:22
|
|
permalink: /en/guide/features/bulletin/
|
|
---
|
|
|
|
## Overview
|
|
|
|
The bulletin is a real-time notification component that enables convenient display of notification messages within the site.
|
|
|
|
Such as the bulletin in the top-right corner.
|
|
|
|
## Usage
|
|
|
|
The theme provides very convenient and flexible methods for using the bulletin.
|
|
You can choose the appropriate configuration method based on your requirements.
|
|
|
|
### Configuration Options
|
|
|
|
```ts title=".vuepress/config.ts"
|
|
import { defineUserConfig } from 'vuepress'
|
|
import { plumeTheme } from 'vuepress-theme-plume'
|
|
|
|
export default defineUserConfig({
|
|
theme: plumeTheme({
|
|
bulletin: {
|
|
// more options...
|
|
}
|
|
})
|
|
})
|
|
```
|
|
|
|
```ts
|
|
interface BulletinOptions {
|
|
/**
|
|
* Bulletin position
|
|
* @default 'top-right'
|
|
*/
|
|
layout?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'center'
|
|
|
|
/**
|
|
* Whether to display gradient border
|
|
*
|
|
* @default true
|
|
*/
|
|
border?: boolean
|
|
|
|
/**
|
|
* Pages where the bulletin is displayed
|
|
*
|
|
* - `true` indicates all pages
|
|
* - `false` indicates no display
|
|
* - Pass a function that returns `true` when display is enabled
|
|
*/
|
|
enablePage?: boolean | ((page: Page) => boolean)
|
|
|
|
/**
|
|
* Bulletin display duration
|
|
*
|
|
* @default 'always'
|
|
*
|
|
* - `'session'`: After closing the bulletin, it won't display again during the current session cycle. It will reappear in new session cycles. Refreshing the page won't make it reappear.
|
|
* - `'always'`: Always display. After closing, refreshing the page will make it reappear.
|
|
* - `'once'`: Display only in the current cycle. After closing, it won't display again. Neither new sessions nor page refreshes will make it reappear.
|
|
*/
|
|
lifetime?: 'session' | 'always' | 'once'
|
|
|
|
/**
|
|
* Bulletin ID
|
|
*
|
|
* The bulletin display duration uses the `id` as a unique identifier
|
|
*/
|
|
id?: string
|
|
|
|
/**
|
|
* Bulletin title
|
|
*/
|
|
title?: string
|
|
|
|
/**
|
|
* Bulletin content
|
|
*
|
|
* Markdown syntax or HTML text can be used.
|
|
* When using markdown, declare `contentType` as `markdown`
|
|
*/
|
|
content?: string
|
|
|
|
/**
|
|
* Bulletin content type
|
|
*
|
|
* - `markdown` indicates using markdown syntax
|
|
* - `text` indicates using plain text (can be HTML content)
|
|
*
|
|
* @default 'text'
|
|
*/
|
|
contentType?: 'markdown' | 'text'
|
|
|
|
/**
|
|
* Pass a `markdown` or `html` file path and use the file content as bulletin content
|
|
*
|
|
* - When using `.md` files, markdown syntax will be parsed
|
|
* - When using `.html` files, only include bulletin content. Please avoid using tags like `<html>`, `<body>`, `<script>`, etc.
|
|
*/
|
|
contentFile?: string
|
|
}
|
|
```
|
|
|
|
## Simple Bulletin
|
|
|
|
When you only need to configure a simple bulletin with brief content, you can directly use `bulletin.content` to add content.
|
|
|
|
```ts title=".vuepress/config.ts"
|
|
export default defineUserConfig({
|
|
theme: plumeTheme({
|
|
bulletin: {
|
|
layout: 'top-right',
|
|
title: 'Bulletin Title',
|
|
content: 'Bulletin content',
|
|
}
|
|
})
|
|
})
|
|
```
|
|
|
|
You can also declare `bulletin.contentType` as `markdown` to use markdown syntax in the `content`.
|
|
|
|
```ts title=".vuepress/config.ts"
|
|
export default defineUserConfig({
|
|
theme: plumeTheme({
|
|
bulletin: {
|
|
layout: 'top-right',
|
|
title: 'Bulletin Title',
|
|
contentType: 'markdown', // [!code hl]
|
|
content: `\
|
|
**Update Notes**
|
|
|
|
- Added some features
|
|
- Fixed some bugs
|
|
`,
|
|
}
|
|
})
|
|
})
|
|
```
|
|
|
|
## Long Content Bulletin
|
|
|
|
When you need to configure a bulletin with lengthy content, writing long content in the configuration file
|
|
may appear bloated and difficult to read. In such cases, use `bulletin.contentFile` to specify a content
|
|
file path, separating the long content from the configuration file.
|
|
|
|
`bulletin.contentFile` requires an absolute path to a `markdown` or `html` file.
|
|
The theme will use the content of this file as the bulletin content.
|
|
|
|
::: code-tabs
|
|
@tab .vuepress/config.ts
|
|
|
|
```ts
|
|
import path from 'node:path'
|
|
|
|
export default defineUserConfig({
|
|
theme: plumeTheme({
|
|
bulletin: {
|
|
layout: 'top-right',
|
|
title: 'Bulletin Title',
|
|
contentFile: path.join(__dirname, '_bulletin.md'),
|
|
}
|
|
})
|
|
})
|
|
```
|
|
|
|
@tab .vuepress/_bulletin.md
|
|
|
|
```md
|
|
**Update Notes**
|
|
|
|
- Added some features
|
|
- Fixed some bugs
|
|
```
|
|
|
|
:::
|
|
|
|
The theme monitors changes to `bulletin.contentFile`. When the file content changes, the bulletin will be re-rendered.
|
|
|
|
## Bulletin with Custom Content Interactions
|
|
|
|
Using `bulletin.content` or `bulletin.contentFile` only allows writing plain text bulletin content and
|
|
some interactive content supported by `markdown` syntax. It does not support writing bulletin content with other custom interactions.
|
|
|
|
For such scenarios, the theme also provides corresponding support.
|
|
|
|
First, configure the basic content of `bulletin`. You don't need to configure `bulletin.content` or `bulletin.contentFile` at this point.
|
|
|
|
```ts title=".vuepress/config.ts"
|
|
export default defineUserConfig({
|
|
theme: plumeTheme({
|
|
bulletin: {
|
|
layout: 'top-right',
|
|
title: 'Bulletin Title',
|
|
}
|
|
})
|
|
})
|
|
```
|
|
|
|
Then, register the global component `BulletinContent` in `.vuepress/client.ts`.
|
|
The theme will automatically detect this component and use it as the bulletin content.
|
|
|
|
```ts title=".vuepress/client.ts"
|
|
import { defineClientConfig } from '@vuepress/client'
|
|
import BulletinContent from './components/BulletinContent.vue'
|
|
|
|
export default defineClientConfig({
|
|
enhance: ({ app }) => {
|
|
app.component('BulletinContent', BulletinContent)
|
|
}
|
|
})
|
|
```
|
|
|
|
Next, write the `BulletinContent.vue` component.
|
|
|
|
```vue title=".vuepress/components/BulletinContent.vue"
|
|
<script setup>
|
|
// Write custom bulletin content interactions
|
|
</script>
|
|
|
|
<template>
|
|
<div class="bulletin-content">
|
|
<!-- Custom bulletin content -->
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
/* Custom bulletin content styles */
|
|
</style>
|
|
```
|
|
|
|
## Custom Bulletin Styles
|
|
|
|
You can directly override the bulletin styles via CSS.
|
|
|
|
Modify the following CSS variables to easily control the bulletin styles.
|
|
|
|
```css
|
|
:root {
|
|
--vp-bulletin-bg-color: var(--vp-c-bg);
|
|
--vp-bulletin-text-color: var(--vp-c-text-1);
|
|
--vp-bulletin-title-color: var(--vp-c-text-1);
|
|
--vp-bulletin-font-size: 16px;
|
|
--vp-bulletin-title-font-size: 18px;
|
|
--vp-bulletin-line-height: 24px;
|
|
--vp-bulletin-border-width: 2px;
|
|
--vp-bulletin-border: conic-gradient(var(--vp-c-important-3), var(--vp-c-danger-3), var(--vp-c-success-3), var(--vp-c-important-3));
|
|
--vp-bulletin-width: 320px;
|
|
}
|
|
```
|
|
|
|
Alternatively, override the bulletin styles globally via the `.vp-bulletin` class.
|
|
|
|
```css
|
|
.vp-bulletin {
|
|
/* Bulletin styles */
|
|
}
|
|
```
|
|
|
|
## Fully Custom Bulletin
|
|
|
|
When you don't want to use the theme's built-in bulletin at all, you can completely customize the
|
|
bulletin by registering a global `Bulletin` component.
|
|
|
|
::: code-tabs
|
|
@tab .vuepress/client.ts
|
|
|
|
```ts
|
|
import { defineClientConfig } from '@vuepress/client'
|
|
import Bulletin from './components/Bulletin.vue'
|
|
|
|
export default defineClientConfig({
|
|
enhance: ({ app }) => {
|
|
app.component('Bulletin', Bulletin)
|
|
}
|
|
})
|
|
```
|
|
|
|
:::
|
|
|
|
Next, write the `Bulletin.vue` component.
|
|
|
|
::: code-tabs
|
|
@tab .vuepress/components/Bulletin.vue
|
|
|
|
```vue
|
|
<script setup>
|
|
// Write custom bulletin
|
|
</script>
|
|
|
|
<template>
|
|
<div class="bulletin">
|
|
<!-- Custom bulletin -->
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
/* Custom bulletin styles */
|
|
</style>
|
|
```
|
|
|
|
:::
|
|
|
|
You need to write the bulletin component from scratch. To facilitate writing the bulletin, the theme
|
|
provides the composable API `useBulletinControl()`, which you can use directly in the `Bulletin.vue` component.
|
|
|
|
```ts
|
|
import { useBulletinControl } from 'vuepress-theme-plume/composables'
|
|
|
|
const {
|
|
bulletin, // Bulletin configuration, read from theme configuration
|
|
showBulletin, // Whether to show the bulletin
|
|
enableBulletin, // Whether the bulletin is enabled on the current page
|
|
close, // Close the bulletin
|
|
} = useBulletinControl()
|
|
```
|
|
|
|
## Related Notes
|
|
|
|
### Bulletin Unique Identifier
|
|
|
|
The bulletin's unique identifier is configured via `bulletin.id`.
|
|
|
|
The unique identifier is used to distinguish bulletins and determine the validity period of `bulletin.lifetime` based on this identifier.
|
|
|
|
```ts
|
|
export default defineUserConfig({
|
|
theme: plumeTheme({
|
|
bulletin: {
|
|
layout: 'top-right',
|
|
title: 'Bulletin Title',
|
|
id: 'my-bulletin', // [!code hl]
|
|
}
|
|
})
|
|
})
|
|
```
|
|
|
|
When you don't explicitly configure `bulletin.id`, the theme generates a hash value based on the `bulletin` object as the unique identifier.
|
|
|
|
### Bulletin Display Duration
|
|
|
|
The bulletin display duration is configured via `bulletin.lifetime`.
|
|
|
|
- `session`: During the current session cycle, if the user doesn't close the bulletin,
|
|
it will continue to display, including into the next session cycle. When the user closes the bulletin,
|
|
it is considered expired and won't display again during the current session cycle, but will reappear in the next session cycle.
|
|
|
|
- `always`: Even if the user closes the bulletin, it will reappear not only in the next session cycle but also when refreshing the page.
|
|
|
|
- `once`: Once the bulletin is closed during the current session cycle, it won't display again afterward.
|
|
|
|
::: details What is a session?
|
|
**Session** refers to the period when you visit a site. As long as the browser tab where the site is
|
|
located remains open, the site maintains the same session, even if the page is refreshed.
|
|
:::
|
|
|
|
### Bulletin Position
|
|
|
|
The bulletin position is configured via `bulletin.layout`.
|
|
|
|
- `top-left`: Top left
|
|
- `top-right`: Top right
|
|
- `bottom-left`: Bottom left
|
|
- `bottom-right`: Bottom right
|
|
- `center`: Top center
|
|
|
|
### Pages Where Bulletin is Displayed
|
|
|
|
The pages where the bulletin is displayed are configured via `bulletin.enablePage`.
|
|
|
|
- `true` indicates all pages
|
|
- `false` indicates no display
|
|
- Pass a function that returns `true` when display is enabled
|
|
|
|
```ts
|
|
export default defineUserConfig({
|
|
theme: plumeTheme({
|
|
bulletin: {
|
|
layout: 'top-right',
|
|
title: 'Bulletin Title',
|
|
enablePage: (page) => {
|
|
return page.path === '/custom-path/'
|
|
}
|
|
}
|
|
})
|
|
})
|
|
```
|