Pular para o conteúdo principal

Primeiro componente

Nesta seção, vamos aprender como criar o nosso primeiro componente no CMS.

Dica

Antes de iniciar a criação do seu primeiro componente, siga as instruções de Configurações iniciais. 👍

Fazendo o componente aparecer no CMS

Criando um componente no CMS

Vamos começar criando um componente de exemplo:

./src/components/ExampleComponent/ExampleComponent.tsx
import type { CmsFunctionalComponent } from "@m3cms/react"

export type ExampleComponentProps = {
text: string
}

const ExampleComponent: CmsFunctionalComponent<ExampleComponentProps> = ({ text }) => {
return (
<div>
<h1>{text}</h1>
</div>
)
}

export default ExampleComponent

Crie um arquivo com o schema do seu componente usando o seguinte template:

./src/components/ExampleComponent/ExampleComponent.schema.ts
import type { CmsFunctionalComponent } from '@m3cms/react';
import {
default as component,
ExampleComponentProps as Props
} from './ExampleComponent';

const id = 'ExampleComponent' as const

const defaultContent: CmsFunctionalComponent<Props>["defaultContent"] = {
text: "Example text",
}

const schema: CmsFunctionalComponent<Props>["schema"] = {
title: id,
type: "object",
properties: {
text: {
title: "Texto",
type: "string",
default: defaultContent.text,
description: "Texto do meu componente de exemplo",
},
},
}

component.id = id
component.schema = schema
component.defaultContent = defaultContent

export default component

Diretório CMS

Lembre-se de sempre exportar os componentes que serão utilizados pelo CMS no arquivo index.ts dentro do diretório CMS.

./src/cms/index.ts
import ExampleComponent from "../components/ExampleComponent/ExampleComponent.schema"
import type { CmsFunctionalComponent } from "@m3cms/react"

export const allCmsComponents: CmsFunctionalComponent<any>[] = [
ExampleComponent,
]

Renderizando o componente em alguma página

Para renderizar o componente em uma página, vamos utilizar o componente CmsComponent do pacote @m3cms/react. Ele será responsável por renderizar o componente e fazer a comunicação com o CMS (Ele que faz a mágica acontecer_ 🪄🐰).

./pages/index.tsx
import { CmsComponent, CmsPageProvider } from "@m3cms/react"
import ExampleComponent from "../components/ExampleComponent/ExampleComponent.schema"

// ...

function Page () {
// ...

return(
<>
// ...
<CmsPageProvider/>
<CmsComponent
tag={"ComponentExempleTag"}
component={ExampleComponent}
/>
// ...
</>
)
}

Após fazer isso, acesse o ambiente do CMS e você já conseguirá visualizar o componente renderizado na página e reconhecido pelo CMS.

info

Lembre-se sempre de renderizar o componente CmsComponent ou CmsComponentSwitch na página juntamente com o componente CmsPageProvider, para que o CMS possa entender que a página está sendo gerenciada por ele.

Componente no Cms

Persistindo dados salvos no CMS

Até este ponto, nosso componente apenas renderiza o texto que foi modificado enquanto está sendo editado no admin do CMC, mas não persiste esses dados quando saímos da página e voltamos.

Passando dados salvos do CMS para o componente

Para resolver isso, vamos fazer uma requisição para o servidor do CMS, buscando os dados salvos no CMS e utilizá-los para renderizar o componente com os dados salvos.

Como estamos usando Next.js, utilizaremos o getServerSideProps para fazer essa requisição antes de renderizar a página e passar os dados para o componente diretamente do servidor. Também utilizaremos a biblioteca @m3cms/api para realizar a requisição para o servidor do CMS, e passaremos para ela a configuração do CMS que criamos no arquivo m3cms.config.js na raiz do projeto.

./pages/index.tsx
import { CmsComponent, CmsPageProvider } from "@m3cms/react"
import ExampleComponent from "../components/ExampleComponent/ExampleComponent.schema"
import { M3Cms, type CmsComponentsDataResponse } from "@m3cms/api"
import m3CmsConfig from "m3cms.config"
import type { GetServerSideProps } from 'next'

const m3Cms = new M3Cms(m3CmsConfig)

const TAGS = {
componentExemple: "ComponentExempleTag"
}

export type PageProps = {
cmsData: CmsComponentsDataResponse
}
// ...

function Page ({cmsData}: PageProps) {
// ...

return(
<>
// ...
<CmsComponent
tag={TAG.componenteExemplo}
component={ExampleComponent}
content={cmsData[TAGS.componentExemple]}
/>
// ...
</>
)
}

export const getStaticProps: GetServerSideProps<Props> = async () => {
const cmsData = await m3Cms.getCmsComponentsData(Object.values(TAGS))

return {
props: {
cmsData,
},
}
}

Agora você poderá visualizar os dados salvos no CMS sendo renderizados no componente. Se você acessar a página fora do ambiente do CMS, os dados estarão sincronizados com o CMS. Sempre que você modificar os dados no CMS e salvá-los, a página será atualizada com os novos dados após o carregamento.

Cache do getServerSideProps

Em ambiente de desenvolvimento não há cache. No entanto, se estiver em ambiente de produção, você pode querer utilizar o cache do getServerSideProps para reduzir o número de requisições para o servidor do CMS.

Veja a documentação do Next.js explicando como fazer.

Usando o mesmo componente React, mas com dados diferentes

Às vezes, em uma mesma página ou em páginas diferentes, queremos utilizar o mesmo componente React, mas com dados diferentes.

Para resolver isso, é muito simples, pois o CMS guarda e gerencia informações usando a TAG do componente. Logo, se usarmos duas tags diferentes para o mesmo componente, o CMS entenderá que são componentes diferentes e gerenciará os dados deles separadamente.

Portanto, para usar o mesmo componente React, mas com dados diferentes, basta passar tags diferentes para o componente.

./pages/index.tsx
// ...

// Quando você for criar suas tags, crie-as de forma mais descritiva para diferenciar as variantes. 😅
const TAGS = {
componentExemple1: "ComponentExempleTag1",
componentExemple2: "ComponentExempleTag2"
}

// ...
return(
<>
// ...
<CmsComponent
tag={TAG.componenteExemplo}
component={ExampleComponent}
content={cmsData[TAGS.componentExemple1]}
/>
<CmsComponent
tag={TAG.componenteExemplo}
component={ExampleComponent}
content={cmsData[TAGS.componentExemple2]}
/>
// ...
</>
)

// ...

Agora, temos dois estados diferentes do mesmo componente sendo gerenciados pelo CMS.

Perigo de usar a mesma tag para componentes diferentes

Se por algum motivo você passar a mesma tag de forma não intencional, o CMS entenderá que é o mesmo componente e gerenciará os dados deles juntos, sobrepondo um com o outro, mesmo que sejam componentes diferentes.

Sincronização de dados entre páginas

Caso você queira que o mesmo estado de componente se repita em várias páginas, basta passar a mesma tag para o componente em páginas diferentes, que os dados serão sincronizados entre elas.