Zum Inhalt springen

Schnellstart + Next.JS-Frontend

next_js_frontend.png

Sie können eine Demo dieser Vorlage ansehen:

Sie können die Daten in der Demo ändern und die Aktualisierungen sehen, aber sie werden jede Stunde zurückgesetzt.

Holen Sie sich eine Frontend-Vorlage mit Beispiel-CRUD-Ansichten, die Folgendes umfassen:

  • Integration mit Firebase und FireCMS. Komponenten sowohl im Frontend als auch im Admin-Panel wiederverwenden.
  • Live-Vorschau: Sehen Sie, wie die Änderungen im CMS auf der Website widergespiegelt werden, mit exakt demselben Code.
  • UI implementiert mit tailwindcss und Radix UI-Komponenten.
  • Erweiterte Filteroptionen
  • Datenabruf beim Scrollen.
  • Filterstatus in der URL speichern.

Diese Vorlage ist äußerst einfach an Ihre Bedürfnisse anzupassen.

Der einfachste Weg, FireCMS mit Next.js zu verwenden, ist die FireCMS PRO-Starter-Vorlage. Diese Vorlage enthält ein Next.js-Projekt mit bereits konfiguriertem FireCMS.

Sie können ein neues Projekt mit der FireCMS PRO-Vorlage erstellen, indem Sie folgendes ausführen:

npx create-firecms-app

oder

yarn create firecms-app

und die Vorlage FireCMS PRO with Next.js frontend auswählen.

Folgen Sie dann den Anweisungen auf dem Bildschirm, um Ihr Projekt zu erstellen.

Der für Sie generierte Code ist ein Next.JS-Projekt, das in 3 Teile aufgeteilt ist:

  • Eine FireCMS-Instanz zur Verwaltung Ihrer Daten.
  • Eine Frontend-App, die CRUD-Funktionalität für eine Produktkollektion sowie eine Blog-Ansicht implementiert.
  • Ein gemeinsamer Ordner mit gemeinsam genutzten Komponenten.

Sie können FireCMS mit Next.js verwenden. FireCMS ist eine React-Bibliothek, daher können Sie sie mit jedem React-Framework verwenden.

Im Fall von Next.js sind Sie auf die Ausführung von FireCMS auf der Client-Seite beschränkt, da Next.js kein serverseitiges Rendering einiger der von FireCMS verwendeten React-Komponenten unterstützt.

Lassen Sie uns eine App mit FireCMS und Next.js erstellen, bei der der App-Router so konfiguriert ist, dass alle Routen, die mit /cms beginnen, an FireCMS delegiert werden.

Beginnen Sie mit der Erstellung Ihres Next.js-Projekts:

npx create-next-app@latest

Wählen Sie:

  • TypeScript als Sprache
  • ESLint als Linter
  • Tailwind CSS als CSS-Framework
  • src als Root-Verzeichnis
  • Ja zur App-Router-Eingabeaufforderung
  • Ja zum Anpassen des Standard-Import-Alias (optional)

Dann werden wir FireCMS PRO installieren. Beachten Sie, dass wir nicht alle Plugins wie den Kollektion-Editor oder die Datenerweiterung hinzufügen, aber Sie können sie nach Bedarf hinzufügen.

Dann installieren Sie FireCMS und seine Abhängigkeiten:

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-mono

Importieren Sie nun die Tailwind-Konfiguration von FireCMS. Fügen Sie das FireCMS-Preset zu tailwind.config.js hinzu, sowie die Inhaltspfade zum FireCMS-Quellcode, damit die richtigen Tailwind-Klassen aufgenommen werden.

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;

Wir empfehlen, Yarn pnp für dieses Projekt zu deaktivieren. Sie können dies tun, indem Sie die Datei .yarnrc im Root-Verzeichnis Ihres Projekts mit folgendem Inhalt erstellen:

nodeLinker: node-modules

Next.js verwendet einen dateibasierten Router. In diesem Leitfaden werden wir die FireCMS-App in der /cms-Route erstellen, aber Sie können dies an Ihre Bedürfnisse anpassen.

FireCMS verwendet react-router, daher müssen wir Next.js so konfigurieren, dass alle Routen, die mit /cms beginnen, an FireCMS delegiert werden.

In unserem app-Ordner erstellen wir einen Ordner namens cms und darin einen weiteren namens [[...path]]. Dies entspricht jeder Route, die mit /cms beginnt.

Dann erstellen Sie die Datei cms/[[...path]]/page.tsx mit folgendem Inhalt:

Wenn Sie FireCMS nicht im Root-Pfad Ihrer App ausführen, müssen Sie die basePath-Eigenschaft auf den Pfad setzen, unter dem Sie es ausführen. In diesem Fall führen wir es unter /cms aus.

"use client";
import { FireCMSApp } from "@/cms/FireCMSApp";
import { FireCMSRouter } from "@firecms/core";
export default function CMS() {
return <FireCMSRouter basePath={"/cms"}>
<FireCMSApp/>
</FireCMSRouter>;
}

Erstellen Sie jetzt die FireCMS-Komponenten. Erstellen Sie die Datei ./src/cms/FireCMSApp.tsx mit folgendem Inhalt. Denken Sie daran, die firebaseConfig durch Ihre eigene Firebase-Konfiguration zu ersetzen.

"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 config
export 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>
);
}

Erstellen Sie eine Datei namens index.css im Ordner ./src/cms mit folgendem Inhalt:

@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
}

Führen Sie dann einfach folgendes aus:

yarn dev

und navigieren Sie zu http://localhost:3000/cms, um Ihre FireCMS-App in Betrieb zu sehen.

  • Bilder werden in Next.js anders geladen. Sie erhalten ein StaticImageData anstelle der Bild-URL (wie in vite). Sie können es in FireCMS-Komponenten verwenden, die eine URL erwarten, mit der Eigenschaft src:
import logo from "./logo.png";
<FirebaseLoginView
logo={logo.src}/>