Files
vue-journal-layer/app/composables/useJournalLinks.ts
Jakub Zych 102da43f76 feat: opt-in Journal search page and JournalSearchBox
- journal.routes.search (off by default) registers journal-search, the
  results page for ?q= in the API's relevance order (no sort is sent),
  server-rendered with a Polish-aware result count.
- JournalSearchBox: an icon button and a WAI-ARIA combobox with debounced
  ?fields=suggest suggestions, stale answers dropped, query words marked
  ignoring diacritics; a plain GET form without JS.
- The module keeps the search path out of the route cache and the sitemap
  and marks it noindex, follow.
- Client: suggestPosts and the fields option; useJournalLinks.searchLink.
2026-10-30 18:14:05 +01:00

26 lines
1.3 KiB
TypeScript

// Links to Journal views, built from stable route names through
// useLocalePath() (i18n gives every route a per-locale name), never from
// concatenated paths. A link to a disabled view (journal.routes.<key>: false)
// is null; components then render plain text.
import { JOURNAL_ROUTE_NAMES } from '../utils/routes.ts'
import type { JournalRoutes } from '../utils/types.ts'
export function useJournalLinks() {
const localePath = useLocalePath()
const routes = (useRuntimeConfig().public.journal as { routes: JournalRoutes }).routes
const link = (key: keyof JournalRoutes, params?: Record<string, string>, query?: Record<string, string>) =>
routes[key] === false ? null : localePath({ name: JOURNAL_ROUTE_NAMES[key], params, query })
return {
postLink: (slug: string) => link('post', { slug }),
categoryLink: (slug: string) => link('category', { category: slug }),
tagLink: (slug: string) => link('tag', { tag: slug }),
authorLink: (slug: string) => link('author', { author: slug }),
indexLink: (page: number = 1) => link('index', undefined, page > 1 ? { page: String(page) } : undefined),
/** The search page for `q`, or null when journal.routes.search is false. */
searchLink: (q?: string) => link('search', undefined, q ? { q } : undefined),
}
}