Getting started

Project structure

Learn what a new Pluto project contains.

A Pluto project is a Nuxt app. It extends one or more layers.

The blog template

The blog template works with both backends: the Git CMS (no database) and Supabase. With the Git CMS, it has these files:

  • content/posts/ holds the posts as Markdown files (Git CMS only).
  • app/pages/ holds the public pages. They read posts from the Public API with usePlutoPublicList and usePlutoPublicItem.
  • app/components/PostArticle.vue renders one post, with the core component PlutoHtml for the body. The post page and the preview of the post editor (PlutoPostPreview.vue) both use it.
  • app/app.config.ts sets the colors, and tailwind.css imports the Pluto site theme.
  • i18n/locales/ holds the texts of the site, one file per language.
  • nuxt.config.ts extends @plutocms/core and, when needed, sets the plutoGithub options.
  • package.json lists @plutocms/core, nuxt, vue, and vue-router. No other layer is needed.

With Supabase, three things differ, and the CLI sets them:

  • nuxt.config.ts extends @plutocms/supabase-blog. That layer brings @plutocms/supabase and core.
  • package.json also lists @plutocms/supabase-blog, and has the supabase-types script.
  • There is no content/ folder: the posts are in the database.

The pages link to a post by its slug (/posts/<slug>), the same for both backends.

The template has no .env file. The CLI writes it when you create the project. With the Git CMS, Create the GitHub App in the admin gives the GitHub App values. See Quickstart.

The shop template

The shop template (Supabase) has these files:

Its nuxt.config.ts extends @plutocms/supabase-shop and the 3D add-on @plutocms/3d, so a product can have a 3D model. The shop layer brings @plutocms/supabase and core.

The Dashboard only template

The Dashboard only template has no public site:

It has no CSS entry, so core adds its own. See Styles.

A Supabase project (the shop, or the blog with Supabase) does not ship shared/types/supabase.ts. Git ignores it. In development, the server writes the generated database types to this file after it applies the migrations.

app.vue

app.vue wraps the app in PlutoRoot.

app/app.vue
<template>
  <PlutoRoot>
    <NuxtPage />
  </PlutoRoot>
</template>

PlutoRoot includes the admin navbar, NuxtLayout, NuxtLoadingIndicator, and the base styles.

nuxt.config.ts

The config extends the layer for the template. This example shows the core blog template:

nuxt.config.ts
export default defineNuxtConfig({
  extends: ['@plutocms/core'],
  css: ['~/assets/css/tailwind.css']
})

The CMS is on by default. The plutoGithub options have defaults: the storage depends on the mode, and Pluto finds the repository from the environment. The template sets no plutoGithub option: the defaults are enough. See Git CMS reference.

The CSS entry

The app owns the only Tailwind build. The CSS entry starts with three imports:

app/assets/css/tailwind.css
@import 'tailwindcss';
@import '@nuxt/ui';
@import '@plutocms/css';

Add your own @theme after these lines. See Styles.

The admin routes

Core owns the /admin routes. They need no page files in your app.

RoutePurpose
/adminRedirects to /admin/home
/admin/homeThe dashboard
/admin/loginThe sign-in page
/admin/no-accessThe page for a signed-in user with no capability
/admin/not-configuredThe page that shows in production when no backend registers an auth driver
/admin/mediaThe media library, when the backend has a media driver
/admin/settingsThe settings pages
/admin/content/<type>The generated list, new, and edit pages of a content type