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

 
  1. Setting custom fields in your content model
    1. Notion image
      Notion image
  1. Create custom field values of a tag in a tag group
    1. Notion image
  1. Use useField in the resource page to get the corresponding custom field value
    1. <script lang="ts" setup>
      	const customColor = useField('
 

 

useArticle

⚠️
Please only use it and must use it in article layout

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 string
    • apiKey: 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.

⚠️
This function must used in the setup scope
interface 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 the Desk 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 passing false it will load article one by one without wrapping in an array, which is the default behavior for both useArticleLoader and InfiniteScroll
  • 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 of chunk or 0
  • condition Same condition input as useFillArticles, if you didn’t pass it, it will try to use the same desk or tag as the current page
  • exhaustedPolicy It controls how useArticleLoader will do after used all of the articles that matched condition . Default is stop which mean it will stop loading. If you choose show-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 as useFillArticles, 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