Como hospedar um aplicativo Remix?

Back4app Containers Remix Cover

Neste artigo, você aprenderá tudo o que precisa saber para começar a usar o Remix. Veremos seus prós e contras, demonstraremos como criar um aplicativo Remix e, por fim, como implantar o Remix.

O que é Remix?

O Remix é uma estrutura moderna da Web de pilha completa para a criação de aplicativos rápidos, elegantes e resilientes. Ele aproveita o poder da renderização no lado do servidor (SSR), permitindo tempos de carregamento mais rápidos e SEO aprimorado para aplicativos dinâmicos da Web.

Com o Remix, os desenvolvedores podem integrar perfeitamente a lógica do lado do cliente e do lado do servidor em uma base de código unificada. Em comparação com outros frameworks React populares, o Remix faz muitas coisas de forma diferente. Isso inclui:

  1. Roteamento baseado em arquivo (um arquivo no diretório de rotas representa uma rota específica)
  2. Tratamento tradicional de formulários (usando HTML e solicitações HTTP, semelhante ao PHP)
  3. Gerenciamento de estado (o estado é armazenado apenas no servidor)
  4. Carregamento de dados (desacoplado dos componentes)

O Remix foi criado em 2020 e inicialmente estava disponível sob uma taxa de licença anual. Posteriormente, em outubro de 2021, a equipe do Remix decidiu abrir o código-fonte do projeto. Agora ele está disponível sob a licença MIT.

No final de 2022, a Remix foi adquirida pela Shopify por 2,1 bilhões de dólares.

Benefícios do Remix

Vejamos os principais benefícios de usar a estrutura Remix.

Navegação baseada em arquivos

O Remix foi desenvolvido com base no React Router, uma poderosa solução de roteamento do lado do cliente. Na verdade, o Remix foi criado pela mesma equipe de desenvolvedores que criou o React Router.

A estrutura utiliza um sistema de navegação baseado em arquivos, o que simplifica a organização do código. Ele permite que os desenvolvedores associem rotas, componentes e recursos a arquivos ou diretórios específicos.

Veja um exemplo:

app/
└── routes/
    ├── $noteId.tsx              // matches: /<noteId>/
    ├── $noteId_.destroy.tsx     // matches: /<noteId>/destroy
    ├── $noteId_.edit.tsx        // matches: /<noteId>/edit
    ├── _index.tsx               // matches: /
    └── create.tsx               // matches: /create

O melhor de tudo é que ele suporta roteamento aninhado via . Isso resulta em tempos de carregamento mais curtos, melhor tratamento de erros e muito mais!

Renderização no lado do servidor (SSR)

O Remix aproveita o poder da renderização no lado do servidor.

Em aplicativos React básicos, os dados geralmente são obtidos no lado do cliente e, em seguida, injetados no DOM. Isso é conhecido como renderização no lado do cliente (CSR).

O Remix, por outro lado, adota uma abordagem diferente. Primeiro, ele busca os dados no back-end, renderiza o HTML com os dados buscados e, em seguida, fornece-os ao cliente.

A renderização no lado do servidor tende a resultar em melhor desempenho e em aplicativos mais amigáveis para SEO.

Manuseio de formulários

O Remix leva o manuseio da forma de volta ao básico.

Em vez de usar vários componentes controlados e JavaScript, ele usa formulários HTML tradicionais e solicitações HTTP.

Quando um formulário é enviado, ele envia uma solicitação HTTP para uma rota específica, que é processada no lado do servidor usando a função action(). Ele funciona de forma semelhante ao bom e velho PHP.

Isso significa que o Remix não requer absolutamente nenhum JavaScript para processar formulários. Embora isso seja ótimo, pode tornar a validação de formulários e a exibição de erros um pouco mais complicadas.

Gerenciamento do Estado

Nesse contexto, o estado refere-se à sincronização dos dados do servidor e do cliente.

O Remix facilita muito o gerenciamento de estado. Ele elimina a necessidade de Redux, Zustand, React Query, Apollo ou qualquer outra biblioteca de gerenciamento de estado do lado do cliente.

Ao usar o Remix, todo o estado é tratado pelo servidor. O cliente não mantém praticamente nenhum estado; portanto, o processo de sincronização não é necessário.

Os dados do servidor para o cliente são transmitidos por meio de várias funções, como loader() e action().

Transições e UI otimista

As transições Remix tornam a movimentação entre as páginas suave e rápida, carregando dados antecipadamente e usando animações.

A UI otimista reflete instantaneamente as ações do usuário, tornando os sites mais responsivos ao mostrar as alterações antes que elas sejam confirmadas.

As transições e a IU otimista melhoram muito a experiência do usuário, reduzindo a latência percebida e fornecendo feedback imediato.

Limitações do Remix

Embora o Remix seja excelente, ele tem algumas limitações.

Complexo

O Remix não é a estrutura mais fácil de usar, e sua documentação (no momento em que este artigo foi escrito) não é das melhores.

A estrutura também faz muitas coisas de forma diferente do React original. Se você for um desenvolvedor React, talvez leve algum tempo para entender todos os diferentes conceitos do Remix.

Menos popular

O Remix ainda é uma estrutura relativamente nova. Seu lançamento público data apenas de outubro de 2021. Ele é menos maduro e testado em batalha em comparação com alguns concorrentes, como o Next.js.

Observando as estrelas do GitHub, podemos ver que o Remix (27 mil estrelas) é muito menos popular que o Next.js (120 mil estrelas). No momento em que este artigo foi escrito, o Remix não foi adotado por nenhum gigante da tecnologia, exceto pelo Shopify.

Acoplado firmemente

Os aplicativos Remix têm um frontend e um backend fortemente acoplados. Embora essa abordagem funcione para projetos menores, alguns desenvolvedores preferem a flexibilidade de um frontend e backend separados.

Além disso, separar o frontend do backend pode tornar seu código mais fácil de manter e de testar.

Sem SSG ou ISR

O Remix não oferece suporte à geração de sites estáticos (SSG) nem à regeneração estática incremental (ISR).

Como implantar um aplicativo Remix?

Nesta seção, criaremos e implantaremos um aplicativo Remix.

Pré-requisitos

Para acompanhar o processo, você precisará de:

  • Conhecimento básico de TypeScript
  • Experiência com o Docker (e tecnologia de contêineres)
  • Node.js e um IDE JavaScript instalado em seu computador
  • Docker Desktop instalado em seu computador

Visão geral do projeto

Ao longo deste artigo, trabalharemos em um aplicativo Web de anotações. O aplicativo Web permitirá que os usuários criem, recuperem, editem e excluam notas.

Para o backend, utilizaremos o Back4app BaaS, e para o frontend, usaremos a estrutura Remix. Depois que o frontend estiver codificado, nós o implantaremos nos contêineres do Back4app.

O produto final terá a seguinte aparência:

Notas do Back4app Remix

Sugiro que você acompanhe primeiro o aplicativo Web Notes. Após o artigo, você deverá ser capaz de implementar seus próprios aplicativos Remix.

Backend

Nesta seção do artigo, usaremos o Back4app para criar o backend do nosso aplicativo.

Criar aplicativo

Comece fazendo login na sua conta do Back4app (ou criando uma, se ainda precisar obtê-la).

Ao fazer login, você será redirecionado para o portal “My Apps”. Para criar um backend, primeiro você precisa criar um aplicativo Back4app. Para fazer isso, clique em “Build new app” (Criar novo aplicativo).

Painel de controle do Back4app Apps

O Back4app oferece duas soluções:

  1. Backend as a Service (BaaS): uma solução de backend totalmente desenvolvida
  2. Contêineres como serviço (CaaS) — plataforma de orquestração de contêineres baseada em Docker

Como estamos trabalhando em um backend, selecione “Backend as a Service”.

Back4app BaaS Criar

Dê um nome ao seu aplicativo, deixe todo o resto como padrão e clique em “Create” (Criar).

Detalhes do Back4app Create App

A plataforma levará algum tempo para configurar tudo o que é necessário para seu backend. Isso inclui o banco de dados, a interface do aplicativo, o dimensionamento, a segurança etc.

Quando seu aplicativo estiver pronto, você será redirecionado para a visualização do banco de dados em tempo real do aplicativo.

Visualização do banco de dados do Back4app

Banco de dados

Continuando, vamos cuidar do banco de dados.

Como estamos criando um aplicativo relativamente simples, precisaremos apenas de um modelo – vamos chamá-lo de Note. Para criá-lo, clique no botão “Create a class” (Criar uma classe) no canto superior esquerdo da tela.

Dê a ela o nome de Note, ative “Public Read and Write Enabled” e clique em “Create class & add columns”.

Criação da classe de banco de dados do Back4app

Em seguida, adicione as seguintes colunas:

+-----------+--------------+----------------+----------+
| Data type | Name         | Default value  | Required |
+-----------+--------------+----------------+----------+
| String    | emoji        | <leave blank>  | yes      |
+-----------+--------------+----------------+----------+
| String    | title        | <leave blank>  | yes      |
+-----------+--------------+----------------+----------+
| File      | content      | <leave blank>  | no       |
+-----------+--------------+----------------+----------+

Depois de criar a classe, preencha o banco de dados com dados de amostra. Crie algumas notas fornecendo os emojis, os títulos e o conteúdo. Como alternativa, importe essa exportação do banco de dados.

Banco de dados do Back4app preenchido

Ótimo, é isso!

Criamos com sucesso um backend sem escrever nenhum código.

Para saber mais sobre o Backend as a Service, confira o artigo O que é Backend as a Service?

Front-end

Nesta seção do artigo, criaremos o frontend do nosso aplicativo usando a estrutura Remix.

criar-remixar

A maneira mais fácil de inicializar um projeto Remix é por meio do utilitário create-remix. Essa ferramenta cria um projeto Remix pronto para produção.

Ele cuida da estrutura de diretórios e dependências, configura o empacotador, etc.

Crie um novo projeto Remix executando o seguinte comando:

$ npx create-remix@latest remix-notes

Initialize a new git repository? Yes
Install dependencies with npm?   Yes

Se você nunca usou o create-remix, ele será instalado automaticamente.

Depois que o projeto tiver sido criado, altere seu diretório ativo para ele:

$ cd remix-notes

Por fim, inicie o servidor de desenvolvimento:

$ npm run dev

Abra seu navegador da Web favorito e navegue até http://localhost:5173. A página inicial padrão do Remix deve aparecer na sua tela.

TailwindCSS

Para facilitar um pouco nossa vida, usaremos o TailwindCSS. O TailwindCSS é uma estrutura que prioriza a utilidade e permite que você crie rapidamente front-ends sem escrever CSS simples.

Primeiro, instale-o usando o npm:

$ npm install -D tailwindcss postcss autoprefixer

Em seguida, execute tailwindcss init:

$ npx tailwindcss init --ts -p

Isso configurará seu projeto e criará um arquivo tailwind.config.ts na raiz do projeto.

Modifique sua propriedade content da seguinte forma para permitir que o Tailwind saiba em quais arquivos as classes de utilitários serão usadas:

// tailwind.config.ts

import type {Config} from "tailwindcss";

export default {
  content: ["./app/**/*.{js,jsx,ts,tsx}"],  // new
  theme: {
    extend: {},
  },
  plugins: [],
} satisfies Config;

Crie um novo arquivo chamado tailwind.css no diretório do aplicativo com o seguinte conteúdo:

/* app/tailwind.css */

@tailwind base;
@tailwind components;
@tailwind utilities;

Por fim, importe-o no root.tsx por meio de links:

// app/root.tsx

// other imports
import {LinksFunction} from "@remix-run/node";
import stylesheet from "~/tailwind.css?url";

export const links: LinksFunction = () => [
  { rel: "stylesheet", href: stylesheet },
];

// ...

É isso aí!

Instalamos o TailwindCSS com sucesso.

Rotas

Nosso aplicativo Web terá os seguintes pontos de extremidade:

  1. / exibe todas as notas
  2. /create permite que os usuários criem notas
  3. / exibe uma nota específica
  4. / /delete permite que os usuários excluam uma nota específica

Para definir essas rotas, crie a seguinte estrutura de diretórios na pasta do aplicativo:

app/
└── routes/
    ├── $noteId.tsx
    ├── $noteId_.destroy.tsx
    ├── $noteId_.edit.tsx
    ├── _index.tsx
    └── create.tsx

Como você deve ter adivinhado, o prefixo $ é usado para parâmetros dinâmicos e . é usado em vez de /.

Visualizações

Continuando, vamos implementar as exibições.

Para tornar nosso código mais seguro quanto ao tipo, criaremos uma interface chamada Note que se assemelha à nossa classe de banco de dados Note.

Crie uma pasta chamada store e, dentro dela, crie NoteModel.ts com o seguinte conteúdo:

// app/store/NoteModel.ts

export default interface NoteModel {
  objectId: string;
  emoji: string;
  title: string;
  content: string;
  createdAt: Date;
  updatedAt: Date;
}

Em seguida, cole o código de visualização de _index.tsx, $noteId.tsx e create.tsx:

// app/routes/_index.tsx

import {Link, NavLink} from "@remix-run/react";
import NoteModel from "~/store/NoteModel";

const notes = [
  {objectId: "1", emoji: "📝", title: "My First Note"},
  {objectId: "2", emoji: "📓", title: "My Second Note"},
  {objectId: "3", emoji: "📔", title: "My Third Note"},
] as NoteModel[];

export default function Index() {
  return (
        <>
      <Link to={`/create`}>
        <div className="bg-blue-500 hover:bg-blue-600 text-lg font-semibold text-white
         px-4 py-3 mb-2 border-2 border-blue-600 rounded-md"
        >
          + Create
        </div>
      </Link>
      {notes.map(note => (
        <NavLink key={note.objectId} to={`/${note.objectId}`}>
          <div className="hover:bg-slate-200 text-lg font-semibold
            px-4 py-3 mb-2 border-2 border-slate-300 rounded-md"
          >
            {note.emoji} {note.title}
          </div>
        </NavLink>
      ))}
    </>
  );
}
// app/routes/$noteId.tsx

import {Form} from "@remix-run/react";
import NoteModel from "~/store/NoteModel";

const note = {
  objectId: "1", emoji: "📝", title: "My First Note", content: "Content here.",
  createdAt: new Date(), updatedAt: new Date(),
} as NoteModel;

export default function NoteDetails() {
  return (
    <>
      <div className="mb-4">
        <p className="text-6xl">{note.emoji}</p>
      </div>
      <div className="mb-4">
        <h2 className="font-semibold text-2xl">{note.title}</h2>
        <p>{note.content}</p>
      </div>
      <div className="space-x-2">
        <Form
          method="post" action="destroy"
          onSubmit={(event) => event.preventDefault()}
          className="inline-block"
        >
          <button
            type="submit"
            className="bg-red-500 hover:bg-red-600 font-semibold text-white
              p-2 border-2 border-red-600 rounded-md"
          >
            Delete
          </button>
        </Form>
      </div>
    </>
  );
}
// app/routes/create.tsx

import {Form} from "@remix-run/react";

export default function NoteCreate() {
  return (
    <>
      <div className="mb-4">
        <h2 className="font-semibold text-2xl">Create Note</h2>
      </div>
      <Form method="post" className="space-y-4">
        <div>
          <label htmlFor="emoji" className="block">Emoji</label>
          <input
            type="text" id="emoji" name="emoji"
            className="w-full border-2 border-slate-300 p-2 rounded"
          />
        </div>
        <div>
          <label htmlFor="title" className="block">Title</label>
          <input
            type="text" id="title" name="title"
            className="w-full border-2 border-slate-300 p-2 rounded"
          />
        </div>
        <div>
          <label htmlFor="content" className="block">Content</label>
          <textarea
            id="content" name="content"
            className="w-full border-2 border-slate-300 p-2 rounded"
          />
        </div>
        <div>
          <button
            type="submit"
            className="bg-blue-500 hover:bg-blue-600 font-semibold
              text-white p-2 border-2 border-blue-600 rounded-md"
          >
            Create
          </button>
        </div>
      </Form>
    </>
  );
}

Não há nada de sofisticado nesse código. Tudo o que fizemos foi usar JSX em combinação com TailwindCSS para criar a interface do usuário.

Como você deve ter notado, todos os componentes não são controlados (não estamos usando useState()). Além disso, estamos usando um formulário HTML real.

Isso ocorre porque a estrutura Remix lida com formulários semelhantes ao PHP usando solicitações HTTP, ao contrário do React.

Parse

Há várias maneiras de se conectar ao seu backend baseado no Back4app. Você pode usar:

  1. API RESTful
  2. API GraphQL
  3. SDK do Parse

A maneira mais fácil e mais robusta é certamente o Parse SDK. O Parse SDK é um kit de desenvolvimento de software que fornece várias classes de utilitários e métodos para consultar e manipular facilmente seus dados.

Comece instalando o Parse via npm:

$ npm install -i parse @types/parse

Crie um arquivo .env na raiz do projeto da seguinte forma:

# .env

PARSE_APPLICATION_ID=<your_parse_app_id>
PARSE_JAVASCRIPT_KEY=<your_parse_js_key>

Certifique-se de substituir <your_parse_app_id> e <your_parse_js_key> pelas credenciais reais. Para obter as credenciais, navegue até seu aplicativo e selecione “App Settings > Server & Security” na barra lateral.

Em seguida, inicialize o Parse na parte superior do arquivo root.tsx da seguinte forma:

// app/root.tsx

// other imports
import Parse from "parse/node";

const PARSE_APPLICATION_ID = process.env.PARSE_APPLICATION_ID || "";
const PARSE_HOST_URL = "https://parseapi.back4app.com/";
const PARSE_JAVASCRIPT_KEY = process.env.PARSE_JAVASCRIPT_KEY || "";
Parse.initialize(PARSE_APPLICATION_ID, PARSE_JAVASCRIPT_KEY);
Parse.serverURL = PARSE_HOST_URL;

Criaremos um arquivo separado chamado api/backend.ts para manter nossas exibições livres da lógica de comunicação do backend.

Crie api/backend.ts com o seguinte conteúdo:

// app/api/backend.ts

import Parse from "parse/node";
import NoteModel from "~/store/NoteModel";

export const serializeNote = (note: Parse.Object<Parse.Attributes>): NoteModel => {
  return {
    objectId: note.id,
    emoji: note.get("emoji"),
    title: note.get("title"),
    content: note.get("content"),
    createdAt: new Date(note.get("createdAt")),
    updatedAt: new Date(note.get("updatedAt")),
  };
}

export const getNotes = async (): Promise<NoteModel[]> => {
  // ...
}

export const getNote = async (objectId: string): Promise<NoteModel | null> => {
  // ...
}

// Grab the entire file from: 
// https://github.com/duplxey/back4app-containers-remix/blob/master/app/api/backend.ts

Por fim, modifique as exibições para buscar e manipular os dados do backend:

// app/routes/index.tsx

import {json} from "@remix-run/node";
import {Link, NavLink, useLoaderData} from "@remix-run/react";
import {getNotes} from "~/api/backend";

export const loader = async () => {
  const notes = await getNotes();
  return json({notes});
};

export default function Index() {
  const {notes} = useLoaderData<typeof loader>();
  return (
    // ...
  );
}
// app/routes/$noteId.tsx

import {getNote} from "~/api/backend";
import {json, LoaderFunctionArgs} from "@remix-run/node";
import {Form, useLoaderData} from "@remix-run/react";
import {invariant} from "@remix-run/router/history";

export const loader = async ({params}: LoaderFunctionArgs) => {
  invariant(params.noteId, "Missing noteId param");
  const note = await getNote(params.noteId);
  if (note == null) throw new Response("Not Found", {status: 404});
  return json({note});
};

export default function NoteDetails() {
  const {note} = useLoaderData<typeof loader>();
  return (
    // ...
  );
}
// app/routes/create.tsx

import {ActionFunctionArgs, redirect} from "@remix-run/node";
import {Form} from "@remix-run/react";
import {createNote} from "~/api/backend";

export const action = async ({request}: ActionFunctionArgs) => {
  const formData = await request.formData();
  const {emoji, title, content} = Object.fromEntries(formData) 
                                    as Record<string, string>;
  const note = await createNote(emoji, title, content);
  return redirect(`/${note?.objectId}`);
};

export default function NoteCreate() {
  return (
    // ...
  );
}
// app/routes/$noteId_.destroy.tsx

import type {ActionFunctionArgs} from "@remix-run/node";
import {redirect} from "@remix-run/node";
import {invariant} from "@remix-run/router/history";
import {deleteNote} from "~/api/backend";

export const action = async ({params}: ActionFunctionArgs) => {
  invariant(params.noteId, "Missing noteId param");
  await deleteNote(params.noteId);
  return redirect(`/`);
};

Resumo do código:

  • Usamos a função Remix loader() para carregar os dados. Depois que os dados foram carregados, nós os passamos para a exibição como JSON por meio da função json().
  • Usamos a função action() do Remix para lidar com o envio do formulário (por exemplo, POST).
  • O noteId foi passado para as visualizações como um parâmetro.

Agora, o aplicativo deve estar totalmente funcional e sincronizado com o backend do Back4app. Para garantir que tudo esteja funcionando, crie algumas notas, edite-as e, em seguida, exclua-as.

Aplicativo Dockerize

Nesta seção, vamos dockerizar nosso frontend do Remix.

Dockerfile

Um Dockerfile é um arquivo de texto simples que descreve as etapas que o mecanismo do Docker deve executar para construir uma imagem.

Essas etapas abrangem a definição do diretório de trabalho, a especificação da imagem de base, a transferência de arquivos, a execução de comandos e muito mais.

Normalmente, as instruções são representadas em letras maiúsculas e imediatamente seguidas por seus respectivos argumentos.

Para saber mais sobre todas as instruções, consulte a referência do Dockerfile.

Crie um Dockerfile na raiz do projeto com o seguinte conteúdo:

# Dockerfile

FROM node:20

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

EXPOSE 3000

CMD ["npm", "run", "start"]

Esse Dockerfile é baseado na imagem node:20. Ele primeiro define o diretório de trabalho, copia o package.json e instala as dependências.

Depois disso, ele cria o projeto, expõe a porta 3000 e serve o aplicativo.

.dockerignore

Ao trabalhar com o Docker, você geralmente se esforça para criar imagens que sejam as menores possíveis.

Como nosso projeto contém determinados arquivos que não precisam estar na imagem (por exemplo, .git, compilação, configurações do IDE), nós os excluiremos. Para fazer isso, criaremos um arquivo .dockerignore que funciona de forma semelhante a um arquivo .gitignore.

Crie um arquivo .dockerignore na raiz do projeto:

# .dockerignore

.idea/
.cache/
build/
node_modules/

Adapte o .dockerignore de acordo com as necessidades de seu projeto.

Criação e teste

Antes de enviar uma imagem do Docker para a nuvem, é uma boa ideia testá-la localmente.

Primeiro, crie a imagem:

$ docker build -t remix-notes:1.0 .

Em seguida, crie um contêiner usando a imagem recém-criada:

$ docker run -it -p 3000:3000
    -e PARSE_APPLICATION_ID=<your_parse_app_id> 
    -e PARSE_JAVASCRIPT_KEY=<your_parse_javascript_key> 
    -d remix-notes:1.0

Certifique-se de substituir <your_parse_app_id> e <your_parse_javascript_key> pelas credenciais reais.

Seu aplicativo agora deve estar acessível em http://localhost:3000. Ele deve se comportar da mesma forma que antes do processo de dockerização.

Enviar para o GitHub

Para implantar um aplicativo no Back4app Containers, você deve primeiro enviar seu código-fonte para o GitHub. Para fazer isso, você pode seguir estas etapas:

  1. Faça login na sua conta do GitHub (ou registre-se).
  2. Crie um novo repositório do GitHub.
  3. Navegue até seu projeto local e inicialize-o: git init
  4. Adicione todo o código ao sistema de controle de versão: git add .
  5. Adicione a origem remota via git remote add origin
  6. Faça o commit de todo o código via git commit -m "initial commit"
  7. Envie o código para o GitHub git push origin master

Implantar aplicativo

Nesta última seção, implantaremos o frontend nos contêineres do Back4app.

Faça login na sua conta do Back4app e clique em “Build new app” (Criar novo aplicativo) para iniciar o processo de criação do aplicativo.

Back4app Criar aplicativo

Como agora estamos implantando um aplicativo em contêiner, selecione “Containers as a Service” (Contêineres como serviço).

Back4app Containers as a Service (Contêineres como serviço)

Em seguida, você deve vincular sua conta do GitHub à Back4app e importar o repositório que criou anteriormente. Depois de conectado, selecione o repositório.

Seleção do repositório do Back4app

O Back4app Containers permite configurações avançadas. No entanto, para nosso aplicativo simples, as seguintes configurações serão suficientes:

  1. Nome do aplicativo: remix-notes (ou escolha seu nome)
  2. Variáveis de ambiente: PARSE_APPLICATION_ID, PARSE_JAVASCRIPT_KEY

Use os valores que você usou no arquivo .env para as variáveis de ambiente.

Quando terminar de configurar a implementação, clique em “Deploy” (Implementar).

Ambiente de configuração do Back4app

Aguarde alguns instantes para que a implantação seja concluída. Depois de implantado, clique no link verde no lado esquerdo da tela para abrir o aplicativo no navegador.

Para obter um tutorial detalhado, consulte a documentação do Container Remix do Back4app.

Pronto! Seu aplicativo agora está implantado com sucesso e pode ser acessado pelo link fornecido. Além disso, a Back4app emitiu um certificado SSL gratuito para seu aplicativo.

Conclusão

Apesar de ser uma estrutura relativamente nova, o Remix permite que os desenvolvedores criem aplicativos da Web avançados de pilha completa.

A estrutura aborda muitas complexidades dos aplicativos da Web, como manipulação de formulários, gerenciamento de estado e muito mais.

Neste artigo, você aprendeu a criar e implantar um aplicativo Remix. Agora você deve ser capaz de utilizar o Back4app para criar um backend simples e o Back4app Containers para implantar seus aplicativos em contêineres.

O código-fonte do projeto está disponível no repositório back4app-containers-remix.


Leave a reply

Your email address will not be published.