Composables
API reference for composables
setupArticlePage
Obtain article data on the article page.
declare function setupArticlePage(seo?: boolean): Ref<Article>
Parameters
seo
default: true
set to false to disable auto-generated SEO tags.
Returns
type SetupArticlePageReturn = Ref<Article>
interface Article
interface Article {
id: string
blurb?: string | null
published_at?: any | null
slug: string
title: string
cover?: any | null
seo?: any | null
html?: string | null
plaintext?: string | null
plan: ArticlePlan
layout?: { __typename?: 'Layout'; id: string; name: string } | null
relevances: { id: string; title: string }[]
metafields: Array<{
id: string
key: string
type: string
group: {
id: string
key: string
type: string
}
values: Array<{ id: string; value: any }>
}>
desk: Desk
tags: Tag[]
authors: Author[]
}
enum ArticlePlan {
Free = 'free',
Member = 'member',
Subscriber = 'subscriber',
}
interface Desk {
desks: Desk[]
id: string
name: string
slug: string
}
interface Tag {
id: string
slug: string
name: string
}
interface Author {
avatar: string
bio: string
desks: Desk[]
email: string
first_name: string
full_name: string
name: string
id: string
last_name: string
location: string
socials: JSON
website: string
}
Author.name
is alias for Author.full_name
setupDeskPage
Obtain desk data on the desk page.
declare function setupDeskPage(seo?: boolean): Ref<Desk>
Parameters
seo
default: true
set to false to disable auto-generated SEO tags.
Returns
type SetupDeskPageReturn = Ref<Desk>
interface Desk {
desks: Desk[]
id: string
name: string
slug: string
}
setupTagPage
Obtain desk data on the desk page.
declare function setupTagPage(seo?: boolean): Ref<Tag>
Parameters
seo
default: true
set to false to disable auto-generated SEO tags.
Returns
type SetupTagPageReturn = Ref<Tag>
interface Tag {
id: string
slug: string
name: string
}
setupAuthorPage
Obtain desk data on the desk page.
declare function setupAuthorPage(seo?: boolean): Ref<Author>
Parameters
seo
default: true
set to false to disable auto-generated SEO tags.
Returns
type SetupAuthorPageReturn = Ref<Author>
interface Author {
avatar: string
bio: string
desks: Desk[]
email: string
first_name: string
full_name: string
name: string
id: string
last_name: string
location: string
socials: JSON
website: string
}
Author.name
is alias for Author.full_name
setupPage
Obtain corresponding resource data on the resources page.
function setupPage<Type extends PageType>({ type }: { type: Type }): Ref<PageTypeMap[Type]>
type PageType = 'article' | 'desk' | 'tag' | 'author'
interface PageTypeMap {
article: Article
desk: Desk
tag: Tag
author: Author
}
Parameters
- type: return the data of the passed in type.
Returns
interface PageTypeMap {
article: Article
desk: Desk
tag: Tag
author: Author
}
type SetupPageReturn = Ref<PageTypeMap[Type]>
Examples
<script lang="ts" setup> const article = setupPage({ type: 'article' }) <script /> <template> <div> <ul> <li>title: {{ article.title }}</li> </ul> </div> </template>
useField
Obtain custom field values through useField
.
function useField<Type extends FieldType>(key: string, type: Type): UseFieldReturn<Type, false>
function useField<Type extends FieldType, IsAll extends boolean>(
key: string,
type: Type,
all: IsAll
): UseFieldReturn<Type, IsAll>
enum FieldType {
Text = 'TEXT',
Number = 'NUM',
Bool = 'BOOL',
File = 'FILE',
URL = 'URL',
Color = 'COLOR',
Date = 'DATE',
RichText = 'RICHTEXT',
Json = 'JSON',
Ref = 'REF',
}
interface FieldTypeMap {
[FieldType.Text]: string
[FieldType.Number]: number
[FieldType.Bool]: boolean
[FieldType.File]: string
[FieldType.URL]: string
[FieldType.Color]: string
[FieldType.Date]: Date
[FieldType.RichText]: unknown
[FieldType.Json]: unknown
[FieldType.Ref]: unknown
}
type UseFieldReturn<Type, IsAll extends boolean> = Type extends FieldType
? IsAll extends true
? Ref<FieldTypeMap[Type][]>
: Ref<FieldTypeMap[Type]>
: IsAll extends true
? Ref<unknown[]>
: Ref<unknown>
Parameters
- key: the format of the key is
<group key>.<field key>
- type: type of custom field
- all: setting
true
will return an array of all values of the field
Returns
interface FieldTypeMap {
[FieldType.Text]: string
[FieldType.Number]: number
[FieldType.Bool]: boolean
[FieldType.File]: string
[FieldType.URL]: string
[FieldType.Color]: string
[FieldType.Date]: Date
[FieldType.RichText]: unknown
[FieldType.Json]: unknown
[FieldType.Ref]: unknown
}
Examples
Using the custom field value of a tag group
- Setting custom fields in your content model
- Create custom field values of a tag in a tag group
- Use
useField
in the resource page to get the corresponding custom field value
<script lang="ts" setup>
const customColor = useField('
useArticle
Get article data
Examples
<script lang="ts" setup>
const article = useArticle()
const { title, blurb } = article
</script>
<template>
<div>{{ article.title }}</div>
<div>{{ article.blurb }}</div>
</template>
useRecommendArticle
get recommend articles from an article
params
- article: the article as a recommendation source
- options:
count
: the amount of recommend articles at most (it may less then this number if you don’t have enough article)
return
Ref<ArticleWithURL[]>
list of articles with their respective URLs
type ArticleWithURL = Article & { url: string }
<script lang="ts" setup> const article = useArticle(); const recommendArticles = useRecommendArticle(article, { count: 10 }); </script> <template> <ul> <li v-for="recommendArticle of recommendArticles" :key="recommendArticle.id" > <NuxtLink :to="recommendArticle.url"> {{ recommendArticle.title }} </NuxtLink> </li> </ul> </template>
useSite
Access the metadata for your publication site via this hook
- publication name
- logo
- social links
- favicon
- timezone
enum SocialMediaKey {
Geneva = 'Geneva',
Reddit = 'Reddit',
TikTok = 'TikTok',
Twitter = 'Twitter',
YouTube = 'YouTube',
Facebook = 'Facebook',
LinkedIn = 'LinkedIn',
Whatsapp = 'Whatsapp',
Instagram = 'Instagram',
Pinterest = 'Pinterest',
}
interface Site {
Examples
<script lang="ts" setup> const site = useSite() <script /> <template> <h1>{{ site.publicationName }}</h1> </template>
useSearchClient
interface UseSearchClientInput {
/**
* Fields for query, this is a comma separated string
*/
queryBy?: string
/**
* API key, this will override the key in runtimeConfig
*/
apiKey?: string
}
declare function useSearchClient(params?: UseSearchClientInput): {
searchClient: any;
indexName: string;
}
Parameters
- UseSearchClientInput:
queryBy
: Fields for query, this is a comma separated stringapiKey
: API key, this will override the key in runtimeConfig, usually you won’t need this
Returns
interface UseSearchClientReturn {
searchClient: any;
indexName: string;
}
Examples
<script lang="ts" setup>
useFillArticles
Obtain a specific number of articles that meet the criteria. Every time you called it it will get next n
article without duplicate.
setup
scopeinterface DeskConditionOption {
Parameters
- count:
Required
- Enter the number of articles you need to obtain
- conditionInput:
Optional
- By default, all articles are used for filling. If you need to limit the filling conditions, you can use this option. Pass the desired conditions as an array, and all conditions in the array must be met. When the values in the array are
string
type, the condition defaults to using theDesk name
. If no conditions are provided: - If currently on the desk, tag, or author page: The current desk, tag, or author is used as the condition.
- If not on any of the above pages: The latest articles are loaded.
- conditionMeta:
Optional
cacheKey
: Parameter used to control the internal cache id. This id must be global and unique, otherwise it will cause a conflict. This parameter should not be entered manually, unless you encounter an edge case that requires it.
Returns
type UseFillArticlesReturn = Ref<Article[]>
Examples
<script lang="ts" setup>
const { articles: alphabetArticles } = useFillArticles(10, [
useArticleLoader
Allow articles to be easily loaded into pages such as desk pages, tag pages, etc., automatically reading the current page desk, or accepting the incoming desk as a filter.
// This is same as `useFillArticles`
interface
Parameters
chunk
infinite scroll when loading articles one by one, when passingfalse
it will load article one by one without wrapping in an array, which is the default behavior for bothuseArticleLoader
andInfiniteScroll
preload
the number of articles preloaded at the start, these articles will appear directly in the html. If not given then the default is the amount ofchunk
or 0
condition
Same condition input asuseFillArticles
, if you didn’t pass it, it will try to use the same desk or tag as the current page
exhaustedPolicy
It controls howuseArticleLoader
will do after used all of the articles that matchedcondition
. Default isstop
which mean it will stop loading. If you chooseshow-unmatched
, it will start loading other articles that is not match the condition.
Returns
type UseFillArticlesLoaderReturn = {
preload: Ref<Article[]>
createLoadMore: () => AsyncGenerator<Article | Article[], void, unknown>
loadMore: () => Promise<Article | Article[]>
}
Examples
<script lang="ts" setup>
const { preload, createLoadMore } = useArticleLoader({ preload: 4, chunk: 4 })
</script>
<template>
<div>
<div class="flex gap-2"><ArticleLayout v-for="article of preload" :key="article.id" :article="article" /></div>
<div>Infinite scroll start</div>
<InfiniteScroll v-slot="articles" :source="createLoadMore">
<div class="flex gap-2 mb-2">
<ArticleLayout v-for="article of articles" :key="article.id" :article="article" />
</div>
</InfiniteScroll>
</div>
</template>
useArticlePagination
Allow articles to be easily loaded into pages such as desk pages, tag pages, etc., automatically reading the current page desk, or accepting the incoming desk as a filter.
export interface UseArticlePaginationInput {
/**
* limit pre page articles
*/
limit: MaybeRef<number>
/**
* filter article
* @see useFillArticles
*/
conditions?: ConditionInput[]
}
export interface UseArticlePaginationReturn {
/**
* current page number
*
* it's ok to modify the page number directly if you need to jump to a specific page
*/
page: Ref<number>
/**
* total amount of pages
*/
total: Ref<number>
/**
* articles for current page
*/
articles: Ref<Article[]>
/**
* A boolean to indicate that is there has next page
*/
hasNextPage: Ref<boolean>
/**
* A boolean to indicate that is there has previous page
*/
hasPreviousPage: Ref<boolean>
/**
* switch to next page
*/
nextPage: () => void
/**
* switch to previous page
*/
previousPage: () => void
}
/**
* A helper to help you build a pagination page to list articles
* @param options Options for article pagination
* @returns
*/
export declare function useArticlePagination(options: UseArticlePaginationInput): UseArticlePaginationReturn;
Parameters
limit
限制一頁的文章數量
condition
Same condition input asuseFillArticles
, if you didn’t pass it, it will try to use the same desk or tag as the current page
Examples
<script lang="ts" setup>
const { articles, previousPage, nextPage } = useArticlePagination({ limit: 5 })
</script>
<template>
<div>
<div class="flex gap-2">
<button @click="previousPage">prev</button>
<button @click="nextPage">next</button>
</div>
<div class="grid grid-cols-2">
<div v-for="article of articles" :key="article.id" />
<!-- use article -->
</div>
</div>
</div>
</template>
useLoadMore
This hook makes it easy to implement infinite scroll, read more articles, etc.
declare function useLoadMore<T>(generatorSource: () => AsyncGenerator<T>): {
loading: Ref<boolean>
isDone: Ref<boolean>
list: Article[]
loadMore: () => Promise<T | undefined>
onLoadMore: EventHookOn<T>
onLoadDone: EventHook<void>
}
Parameters
- generatorSource:
Required
- An AsyncGenerator is passed in as an argument, and the source object created by the generatorSource returns a set of content data each time
.next()
is called.
Returns
interface UseLoadMoreReturn {
Examples
<script setup lang="ts">
async function* GenSource() {
const articles = await getAllArticles()
for (const article of articles) {
yield article
}
}
const { loading, list, loadMore, onLoadMore, onLoadDone } = useLoadMore(GenSource)
onLoadMore((item) => {})
onLoadDone(() => {})
const onClick = async () => {
if (loading) return
await loadMore()
}
</script>
<template>
<div>
<div v-for="(article, index) of list" :key="index">
<ArticleLayout :article="article" />
</div>
<div v-if="loading">Loading...</div>
</div>
<button @click="onClick">more</button>
</template>
useDesks
This hook used to retrieve a list of desks with URLs and return as an array of objects, which can be used to render a list of links to the desks on a page.
function useDesks(): {
desks: Ref<DeskWithURL[] | null>
}
Returns
type UseDesksReturn = Ref<DeskWithURL[]>
interface Desk {
id: string
name: string
slug: string
desks: Desk | null
}
interface DeskWithURL extends Desk {
url: string
desks: DeskWithURL | null
}
Examples
<script lang="ts" setup>
const { desks } = useDesks()
</script>
<template>
<ul>
<li v-for="desk of desks" :key="desk.id">
<NuxtLink :to="desk.url">
{{ desk.name }}
</NuxtLink>
</li>
</ul>
</template>
useTagGroup
Given a tag group key, the hooks return a list of tags that belong to this group, including their corresponding URLs.
function useTagGroup(groupKey: string): Ref<{
id: string
name: string
url: string
}[]>
Parameters
groupKey
: Required. Tag group key, will find the tags under that group.
Returns
type UseTagGroupReturn = Ref<TagGroup[]>
interface TagGroup {
id: string
name: string
url: string
}
Examples
<script lang="ts" setup>
const tags = useTagGroup('example_group')
</script>
<template>
<ul>
<li v-for="tag of tags" :key="tag.id">
<NuxtLink :to="tag.url">
{{ tag.name }}
</NuxtLink>
</li>
</ul>
</template>
Last updated on February 16, 2023