Skip to main content

Pages

Add pages on Clubs with your plugin. Pages are mainly composed of paths and components, which are combined with the layout components exported by a theme plugin to be displayed on the screen.

Page components can use UI frameworks such as React, Svelte, Vue, Lit, etc. via Astro components, so you can build anything from simple to complex there.

getPagePaths

getPagePaths is an asynchronous function that generates pages and returns an array of ClubsStaticPaths to define pages and their contents, etc.

Clubs runtime passes 3 arguments to getPagePaths, plugin options, config, and utils. And the return value should be an array of objects with the following values:

RequiredTypeDescription
pathsRequiredarray includes string, RegExp or undefinedPath to determine the URL of the generated page.
componentRequiredAstro componentContent of the generated page.
propsObjectObject passed to Astro.props
layoutAstro componentLayout component used by the page. When exporting layout, it overrides the layout components exported by the theme plugin.

The returns value

The return value of getPagePaths should be an array of objects with these properties.

paths

If paths joined with / matches the pathname in the HTML request, the component will be rendered as the page content.

For example, if you want to add /vote/open, paths should be the following value:

["vote", "open"]

If you would like to render the component as the primary page of your Clubs, you can define it as an empty array, or an array containing only undefined, like this:

[]
// OR
[undefined]
info

// TODO: Add a note about RegExp path

component

Components must always be Astro components. If you want to use a UI framework such as React or Svelte, for example, you can export an Astro component that renders a React component.

/src/index.ts
import { default as MyAstroComponent } from './components/MyAstroComponent.astro'

const getPagePaths = async () => [
{
component: MyAstroComponent,
paths: [],
},
]

export default {
getPagePaths,
meta: {
/*...*/
},
}
/src/components/MyAstroComponent.astro
---
import {MyReactComponent} from './MyReactComponent'
---

<MyReactComponent client:load />
/src/components/MyReactComponent.tsx
import React from 'react'

export const MyReactComponent = () => <p>Hello, world!</p>

props

If a component has values that it expects to be injected from the outside, you can pass those values through defining props.

/src/index.ts
import { default as MyAstroComponent } from './components/MyAstroComponent.astro'

const getPagePaths = async () => [
{
component: MyAstroComponent,
props: {
str: 'me',
},
paths: [],
},
]

export default {
getPagePaths,
meta: {
/*...*/
},
}
/src/components/MyAstroComponent.astro
---
import {MyReactComponent} from './MyReactComponent'

const { str } = Astro.props as {str: string}
---

<MyReactComponent client:load str={str} />
/src/components/MyReactComponent.tsx
import React from 'react'

export const MyReactComponent = ({ str }: { str: string }) => (
<p>Hello, {str}!</p>
)

signals

The style of the page components in final rendering depends on the theme. If you want to control it how, signals is the best way to do so.

props.signals is a special props that allows you to signal how the enabled theme should handle the page component by passing an array including string or enum type ClubsPluginSignal(*). Note that signals are optionally supported by themes.

ClubsPluginSignal contains the following signals:

  • DisplayWideWidth = display:wide-width
  • DisplayFullWidth= display:full-width
  • DisplayFullPage = display:full-pages
/src/index.ts
import { default as MyAstroComponent } from './components/MyAstroComponent.astro'
import { ClubsPluginSignal } from '@devprotocol/clubs-core'

const getPagePaths = async () => [
{
component: MyAstroComponent,
props: {
signals: [ClubsPluginSignal.DisplayWideWidth]
str: 'me',
},
paths: [],
},
]

export default {
getPagePaths,
meta: {
/*...*/
},
}

layout

If you want complete control over the look and feel of the page, you can use layout to override the theme of the page. The page component will be injected into <slot /> of the layout.

/src/index.ts
import { default as MyAstroComponent } from './components/MyAstroComponent.astro'
import { default as MyLayout } from './components/MyLayout.astro'

const getPagePaths = async () => [
{
component: MyAstroComponent,
props: {
str: 'me',
},
layout: MyLayout,
paths: [],
},
]

export default {
getPagePaths,
meta: {
/*...*/
},
}
/src/components/MyLayout.astro
---
console.log(Astro.props)
// -> {str: "me"}
// Layout component receives the same `props` as `component`
---

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
</head>

<body>
<main>
<slot /> // `component` will be rendered here
</main>
</body>
</html>

Use plugin options

The 1st argument of getPagePaths is passed an object plugin options, has type ClubsPluginOptions(*). By controlling the return value of getPagePaths with plugin options, you can control the page's functionality of the page.

/src/index.ts
import { default as MyAstroComponent } from './components/MyAstroComponent.astro'

const getPagePaths = async (options) => {
const str = options.find(({ key }) => key === 'content')?.value ?? 'me'

return [
{
component: MyAstroComponent,
props: {
str,
},
paths: [],
},
]
}

export default {
getPagePaths,
meta: {
/*...*/
},
}
info

The details of the plugin options are found on ClubsPluginOptions.

Use configuration

The 2nd argument of getPagePaths is passed an object config, has type ClubsConfiguration(*). By controlling the return value of getPagePaths with config, you can control the page's functionality of the page.

ClubsConfiguration contains major primitive configuration values such as Clubs name, property token address, chain ID which tokenized it, URL of Json-RPC endpoint, etc.

/src/index.ts
import { default as MyAstroComponent } from './components/MyAstroComponent.astro'

const getPagePaths = async (options, config) => {
const str = options.find(({ key }) => key === 'content')?.value ?? 'me'
const { rpcUrl } = config

return [
{
component: MyAstroComponent,
props: {
str,
rpcUrl,
},
layout: MyLayout,
paths: [],
},
]
}

export default {
getPagePaths,
meta: {
/*...*/
},
}
info

The details of the config are found on ClubsConfiguration.

Use utils

The 3rd argument of getPagePaths is passed an object utils, has type ClubsFactoryUtils(*). ClubsFactoryUtils has a function getPluginConfigById that allows users to retrieve configuration values for other plugins using getPluginConfigById.

/src/index.ts
import { default as MyAstroComponent } from './components/MyAstroComponent.astro'

const getPagePaths = async (options, config, utils) => {
const str = options.find(({ key }) => key === 'content')?.value ?? 'me'
const { rpcUrl } = config
const emojiPlugin = utils.getPluginConfigById('emoji:plugin:id') // Find a config of a plugin that has `meta.id: "emoji:plugin:id"`
const emoji =
emojiPlugin?.options?.find(({ key }) => key === 'emoji')?.value ?? '🦄'

return [
{
component: MyAstroComponent,
props: {
str,
rpcUrl,
emoji,
},
layout: MyLayout,
paths: [],
},
]
}

export default {
getPagePaths,
meta: {
/*...*/
},
}
info

The details of the utils are found on utils.