Type to search pages and sections.

Skip to content
Ginko

Compare and switch

When Ginko fits, and when Nuxt Content, a hosted CMS or a Git-based editor fits better. What each API of Nuxt Content and @nuxtjs/i18n becomes in Ginko.

Ginko or Nuxt Content

Both read Markdown from content/ and render it in a Nuxt site. They solve different jobs.

Take Ginko when people who are not developers edit the site. The same brick can come from files today and from the platform tomorrow: the site code stays the same. Owners edit in the Studio, with approval, a schedule, history, and a link check before anything goes live. Languages, addresses per language, and hreflang come with it.

Take Nuxt Content when only developers edit, in Git, and you need what Ginko does not have: Nuxt Studio, or more than 500 entries in one collection (Ginko's limit). Ginko has data files in YAML, JSON and CSV and queries with where, order and limit too.

A site can also start with Ginko file bricks only. It then needs no platform and no account.

Ginko, a hosted CMS or a Git-based editor

Owners can also edit a Nuxt site with a hosted CMS, such as Storyblok or Contentful, or with an editor that writes to Git, such as Decap CMS, TinaCMS or Nuxt Studio. Each fits a different team.

GinkoHosted CMSGit-based editor
Where the content model livesin code, ginko.config.tsin the CMSin code or in the editor's config
Where the content liveson the Ginko platform, or as files in the repoin the CMSas files in the repo
What a change doesplatform content goes live without a new build, after approval if the brick asks for it; file content needs a builddepends on the CMS and the site setupbecomes a commit and needs a new build
FrameworksNuxt onlymost frameworksdepends on the editor
Accessthe platform is open by invitationsign-updepends on the editor

Take a hosted CMS when editors build pages from blocks themselves, when many sites in different frameworks share one content store, or when you need its integrations.

Take a Git-based editor when every change should be a commit and the content should never leave the repo.

Take Ginko when the site is Nuxt, a developer defines what owners may change, and owners change it often: opening hours, a menu, events.

When not to use Ginko

  • The site is not built with Nuxt.
  • Editors should arrange pages from sections themselves. Ginko is not a page builder.
  • One collection needs more than 500 entries.
  • The content almost never changes. Plain Nuxt is enough.
  • You need a platform that you can sign up for today. Lupinum opens the Ginko platform by invitation. Without it, you can still use file bricks.

Leaving the platform

ginko export saves the schema, all entries and all files of a site to a folder: export.json plus files/. The folder is a backup in Ginko's own format, not the file layout of content/. To move a brick to files, you convert the entries yourself. See Platform and CLI.

From Nuxt Content

Nuxt ContentGinko
content.config.ts with defineCollectionginko.config.ts with collection({ source: 'files', … })
a schema with Zodfields with f.*: f.text, f.markdown, f.image, …
queryCollection('docs').path(path).first()useGinkoEntry('docs', slug)
queryCollection('blog').where(…).order(…).all()useGinkoQuery('blog', { where, order, limit })
queryCollectionNavigationuseGinkoNav(['docs'])
queryCollectionItemSurroundingsuseGinkoNeighbors('docs', id)
queryCollectionSearchSectionsthe search index at /__ginko/search/<locale>.json
<ContentRenderer :value="page" /><GinkoMarkdown :value="doc.data.body" />
MDC ::calloutthe same syntax; you map names to components with :components
useSeoMeta per pageuseGinkoSeo({ … })

What changes when you move:

  • One file per entry and language. 1.einstieg.md is the main locale, 1.einstieg.en.md the translation. See Content from files.
  • Frontmatter is checked. A key the brick does not know stops the build, with the file and the field in the message.
  • Queries read the bundle. useGinkoQuery runs on the data of the page, not on a database. where takes eq, ne, gt, gte, lt, lte, in, and contains; order is a text like 'date desc' or an object like { field: 'date', dir: 'desc' }.
  • Links between entries follow the language. In Markdown, [Bricks]($docs.bausteine) points to the entry in the language of the page. A link that points nowhere stops the build.

From @nuxtjs/i18n

The Ginko module installs ginko-i18n and gives it the locales of the site. Remove @nuxtjs/i18n: setup stops with a message when both are installed.

@nuxtjs/i18nginko-i18n
i18n: { locales, defaultLocale } in nuxt.config.tslocales in ginko.config.ts; the first one is the main locale
i18n: { strategy } in nuxt.config.tsthe same, in nuxt.config.ts
$t('key'), useI18n().tuseI18n().t
useLocalePath()useI18n().localePath
useSwitchLocalePath(), useLocaleHead()useI18n().alternates; head tags are set for you
defineI18nRoute({ paths })definePageMeta({ i18n: { paths } })
i18n/locales/*.json with vue-i18n syntaxi18n/<code>.json with ICU syntax
detectBrowserLanguageuseLocaleSuggestion(): a link the visitor can choose

What changes when you move:

  • Plurals use ICU. 'no dish | one dish | {count} dishes' becomes '{count, plural, =0 {no dish} one {# dish} other {# dishes}}'.
  • Two strategies. prefix_except_default (the default) and prefix. Domains per language and no_prefix do not exist.
  • The address decides the language. No cookie and no browser header switches a page. For apps behind a login, userLocale lets chosen paths follow the user instead.
  • Detail pages need no extra code. The addresses of an entry in each language come from the bundle, so the language switcher and hreflang are right without setI18nParams.

The details are in Languages.