Quickstart + Frontend Next.JS

Você pode verificar uma demo deste template:
Você pode alterar os dados na demo e ver as atualizações, mas ele é redefinido a cada hora.
Obtenha um template frontend com views CRUD de exemplo que incluem:
- Integração com Firebase e FireCMS. Reutilize componentes tanto no frontend quanto no painel de administração.
- Prévia ao vivo: veja como as mudanças no CMS serão refletidas no site, usando o mesmo código exato.
- UI implementada com tailwindcss e componentes Radix UI.
- Opções de filtragem avançadas
- Busca de dados ao rolar.
- Armazenando o estado de filtro na URL.
Este template é extremamente fácil de personalizar para suas necessidades.
Usando o template starter FireCMS PRO
Seção intitulada “Usando o template starter FireCMS PRO”A maneira mais fácil de usar o FireCMS com o Next.js é usar o template starter FireCMS PRO. Este template inclui um projeto Next.js com o FireCMS já configurado.
Você pode criar um novo projeto usando o template FireCMS PRO executando:
npx create-firecms-appou
yarn create firecms-appe selecionar o template FireCMS PRO with Next.js frontend.
Em seguida, siga as instruções na tela para criar seu projeto.
O que você obtém
Seção intitulada “O que você obtém”O código que será gerado para você é um projeto Next.JS dividido em 3 partes:
- Uma instância do FireCMS para gerenciar seus dados.
- Um app frontend que implementa funcionalidade CRUD para uma coleção de produtos, bem como uma view de blog.
- Uma pasta common com componentes compartilhados.
Configurando o FireCMS com Next.js manualmente
Seção intitulada “Configurando o FireCMS com Next.js manualmente”Você pode usar o FireCMS com o Next.js. O FireCMS é uma biblioteca React, então você pode usá-lo com qualquer framework React.
No caso do Next.js, você está restrito a executar o FireCMS no lado do cliente, pois o Next.js não suporta renderização do lado do servidor de alguns componentes React usados pelo FireCMS.
Vamos criar um app usando FireCMS e Next.js, com o roteador de app configurado para delegar todas as rotas começando com /cms para o FireCMS.
Criar um projeto Next.js
Seção intitulada “Criar um projeto Next.js”Comece criando seu projeto Next.js:
npx create-next-app@latestSelecione:
- TypeScript como idioma
- ESLint como linter
- Tailwind CSS como framework CSS
- src como diretório raiz
- Sim para o prompt do roteador de app
- Sim para personalizar o alias de importação padrão (opcional)
Instalar o FireCMS
Seção intitulada “Instalar o FireCMS”Em seguida, vamos instalar o FireCMS PRO. Note que não adicionaremos todos os plugins como o editor de coleções ou aprimoramento de dados, mas você pode adicioná-los conforme necessário.
Instale o FireCMS e suas dependências:
yarn add firebase@^10 @firecms/core@^3.0.0-beta @firecms/firebase@^3.0.0-beta react-router@^6 react-router-dom@^6 @tailwindcss/typography typeface-rubik @fontsource/jetbrains-monoAgora vamos importar a configuração tailwind do FireCMS. Adicione o preset FireCMS tailwind.config.js, bem como os caminhos de conteúdo para o código-fonte do FireCMS, para que as classes tailwind corretas sejam selecionadas.
import fireCMSConfig from "@firecms/ui/tailwind.config.js";import type { Config } from "tailwindcss";
const config: Config = { presets: [fireCMSConfig], content: [ "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}", "./src/app/**/*.{js,ts,jsx,tsx,mdx}", "./src/cms/**/*.{js,ts,jsx,tsx,mdx}", "./node_modules/@firecms/**/*.{js,ts,jsx,tsx}" ]};export default config;Desabilitar yarn pnp (opcional)
Seção intitulada “Desabilitar yarn pnp (opcional)”Preferimos desabilitar o yarn pnp para este projeto. Você pode fazer isso criando o arquivo .yarnrc na raiz do seu projeto com o seguinte conteúdo:
nodeLinker: node-modulesConfigurando o roteador de App
Seção intitulada “Configurando o roteador de App”O Next.js usa um roteador baseado em arquivos. Neste guia, criaremos o app FireCMS na rota /cms, mas você pode personalizar isso para suas necessidades.
O FireCMS usa react-router, então precisamos configurar o Next.js para delegar todas as rotas começando com /cms para o FireCMS.
Na nossa pasta app, criamos uma pasta chamada cms e dentro dela outra chamada [[...path]]. Isso corresponderá a qualquer rota começando com /cms.
Em seguida, crie o arquivo cms/[[...path]]/page.tsx com o seguinte conteúdo:
Se você não estiver executando o FireCMS no caminho raiz do seu app, you need to set the basePath prop to the path where you are running it. In this case, we are running it in /cms.
"use client";import { FireCMSApp } from "@/cms/FireCMSApp";import { FireCMSRouter } from "@firecms/core";
export default function CMS() { return <FireCMSRouter basePath={"/cms"}> <FireCMSApp/> </FireCMSRouter>;}Criando o CMS
Seção intitulada “Criando o CMS”Agora vamos criar os componentes FireCMS. Crie o arquivo ./src/cms/FireCMSApp.tsx com o seguinte conteúdo. Lembre-se de substituir o firebaseConfig pela sua própria configuração Firebase.
"use client";import React, { useCallback } from "react";
import "./index.css";import "typeface-rubik";import "@fontsource/jetbrains-mono";
import { AppBar, buildCollection, CircularProgressCenter, Drawer, FireCMS, ModeControllerProvider, NavigationRoutes, Scaffold, SideDialogs, SnackbarProvider, useBuildLocalConfigurationPersistence, useBuildModeController, useBuildNavigationController, useValidateAuthenticator} from "@firecms/core";import { FirebaseAuthController, FirebaseLoginView, FirebaseSignInProvider, useFirebaseAuthController, useFirebaseStorageSource, useFirestoreDelegate, useInitialiseFirebase,} from "@firecms/firebase";import { useImportPlugin } from "@firecms/data_import";import { useExportPlugin } from "@firecms/data_export";import { useBuildUserManagement, userManagementAdminViews, useUserManagementPlugin } from "@firecms/user_management";import { useFirestoreCollectionsConfigController } from "@firecms/collection_editor_firebase";import { mergeCollections, useCollectionEditorPlugin } from "@firecms/collection_editor";
//TODO: replace with your own Firebase configexport const firebaseConfig = { //...};
const categories = { fiction: "Fiction", drama: "Drama", "fantasy-fiction": "Fantasy fiction", history: "History", religion: "Religion", "self-help": "Self-Help", "comics-graphic-novels": "Comics & Graphic Novels", "juvenile-fiction": "Juvenile Fiction", philosophy: "Philosophy", fantasy: "Fantasy", education: "Education", science: "Science", medical: "Medical", cooking: "Cooking", travel: "Travel"};
const booksCollection = buildCollection({ name: "Books", singularName: "Book", id: "books", path: "books", icon: "MenuBook", group: "Content", textSearchEnabled: true, description: "Example of a books collection that allows data enhancement through the use of the **OpenAI plugin**", properties: { title: { name: "Title", validation: { required: true }, dataType: "string" }, authors: { name: "Authors", dataType: "string" }, description: { name: "Description", dataType: "string", multiline: true }, spanish_description: { name: "Spanish description", dataType: "string", multiline: true }, thumbnail: { name: "Thumbnail", dataType: "string", url: "image" }, category: { name: "Category", dataType: "string", enumValues: categories }, tags: { name: "Tags", dataType: "array", of: { dataType: "string" } }, published_year: { name: "Published Year", dataType: "number", validation: { integer: true, min: 0 } }, num_pages: { name: "Num pages", dataType: "number" }, created_at: { name: "Created at", dataType: "date", autoValue: "on_create" } }});
export function FireCMSApp() {
const { firebaseApp, firebaseConfigLoading, configError } = useInitialiseFirebase({ firebaseConfig });
// Controller used to manage the dark or light color mode const modeController = useBuildModeController();
const signInOptions: FirebaseSignInProvider[] = ["google.com"];
// Controller for saving some user preferences locally. const userConfigPersistence = useBuildLocalConfigurationPersistence();
// Delegate used for fetching and saving data in Firestore const firestoreDelegate = useFirestoreDelegate({ firebaseApp });
// Controller used for saving and fetching files in storage const storageSource = useFirebaseStorageSource({ firebaseApp });
const collectionConfigController = useFirestoreCollectionsConfigController({ firebaseApp });
// controller in charge of user management const userManagement = useBuildUserManagement({ dataSourceDelegate: firestoreDelegate, });
// Controller for managing authentication const authController: FirebaseAuthController = useFirebaseAuthController({ firebaseApp, signInOptions, loading: userManagement.loading, defineRolesFor: userManagement.defineRolesFor });
const { authLoading, canAccessMainView, notAllowedError } = useValidateAuthenticator({ disabled: userManagement.loading, authenticator: userManagement.authenticator, authController, // authenticator: myAuthenticator, dataSourceDelegate: firestoreDelegate, storageSource });
const collectionsBuilder = useCallback(() => { const collections = [ booksCollection, // Your collections here ]; return mergeCollections(collections, collectionConfigController.collections ?? []); }, [collectionConfigController.collections]);
const navigationController = useBuildNavigationController({ basePath: "/", collections: collectionsBuilder, collectionPermissions: userManagement.collectionPermissions, adminViews: userManagementAdminViews, authController, dataSourceDelegate: firestoreDelegate });
const userManagementPlugin = useUserManagementPlugin({ userManagement });
const importPlugin = useImportPlugin(); const exportPlugin = useExportPlugin();
const collectionEditorPlugin = useCollectionEditorPlugin({ collectionConfigController });
if (firebaseConfigLoading || !firebaseApp) { return <><CircularProgressCenter/></>; }
if (configError) { return <>{configError}</>; } return ( <SnackbarProvider> <ModeControllerProvider value={modeController}> <FireCMS navigationController={navigationController} authController={authController} userConfigPersistence={userConfigPersistence} dataSourceDelegate={firestoreDelegate} storageSource={storageSource} plugins={[importPlugin, exportPlugin, userManagementPlugin, collectionEditorPlugin]} > {({ context, loading }) => {
if (loading || authLoading) { return <CircularProgressCenter size={"large"}/>; } if (!canAccessMainView) { return <FirebaseLoginView authController={authController} firebaseApp={firebaseApp} signInOptions={signInOptions} notAllowedError={notAllowedError}/>; }
return <Scaffold autoOpenDrawer={false}> <AppBar title={"My demo app"}/> <Drawer/> <NavigationRoutes/> <SideDialogs/> </Scaffold>; }} </FireCMS> </ModeControllerProvider> </SnackbarProvider> );
}Importando os estilos padrão do FireCMS
Seção intitulada “Importando os estilos padrão do FireCMS”Crie um arquivo chamado index.css na pasta ./src/cms com o seguinte conteúdo:
@import "@firecms/ui/index.css";@tailwind base;@tailwind components;@tailwind utilities;
:root { --color-primary: #0070F4; --color-secondary: #FF5B79;}
a { @apply text-blue-600 dark:text-blue-400 dark:hover:text-blue-600 hover:text-blue-800}Executar
Seção intitulada “Executar”Em seguida, simplesmente execute:
yarn deve navegue até http://localhost:3000/cms para ver seu app FireCMS em execução.
Algumas considerações
Seção intitulada “Algumas considerações”- As imagens são carregadas de forma diferente no Next.js.
Você obtém um
StaticImageDataem vez da URL da imagem (como no vite). Você pode usá-lo em componentes FireCMS que esperam uma URL, usando a propriedadesrc:
import logo from "./logo.png";
<FirebaseLoginView logo={logo.src}/>