Maily.to Documentation

repository·main·Indexed 26 days ago

https://github.com/arikchakma/maily.to

A specialized editor framework built on Tiptap for creating mobile-ready emails and rich content. It features slash commands, grouped blocks, dynamic variables, and image upload integration. The ecosystem includes @maily-to/core for the editor component, @maily-to/render for converting content to HTML with variable and payload support, and @maily-to/shared for common utilities.

Tokens
11.6K
Snippets
23
Records
84
Agent score
87%

What's inside maily.to

  1. Supported Email Components in Maily

    main

    Maily provides an opinionated set of pre-designed components to ensure email compatibility across platforms and browsers. Supported components include:

    • Logo
    • Buttons and Variants
    • Variables
    • Text Formatting
    • Image
    • Alignment
    • Divider
    • Spacer
    • Footer
    • Inline Code
    • Link Cards
    • Section
    • Columns
    • Repeat
    • Show If Condition
  2. Enable Image Upload

    main

    To support image uploads, add the ImageUploadExtension to the extensions array. Provide an onImageUpload callback that accepts the file, uploads it to your server, and returns the resulting URL.

    import { ImageUploadExtension } from '@maily-to/core/extensions';
    
    <Editor
      extensions={[
        ImageUploadExtension.configure({
          onImageUpload: async (file) => {
            const url = await uploadImage(file);
            return url;
          },
        }),
      ]}
    />
  3. Set up a local development environment

    main

    To run a development version of Maily locally, follow these steps:

    1. Clone the repository.
    2. Navigate to the project directory.
    3. Set up your environment variables by copying the example config.
    4. Configure Google and Github providers in your Supabase project (refer to Supabase auth documentation).
    5. Install dependencies using pnpm.
    6. Start the development server.
    git clone https://github.com/arikchakma/maily.to
    cd maily.to
    cp ./apps/web/.env.example ./apps/web/.env
    pnpm install
    pnpm dev
  4. Access the Maily Editor

    main

    You can start using the Maily Editor immediately by accessing the online playground. This allows you to create beautiful, pre-designed, mobile-ready emails using pre-built components without local setup.

    https://maily.to/playground
  5. Configure Slash Commands and Block Groups

    main

    Slash commands are organized into groups. Each group contains a title and a commands array of BlockItem objects. You can define simple commands or grouped commands with subcommands using an id and a commands array. Subcommands are triggered by typing the id followed by a dot (e.g., /headers.).

    // Example of grouped commands with subcommands
    <Editor
      blocks={[
        {
          title: 'Formatting',
          commands: [
            {
              title: 'Headers',
              id: 'headers',
              searchTerms: ['header', 'title'],
              commands: [
                {
                  title: 'Heading 1',
                  searchTerms: ['h1', 'heading1'],
                  command: ({ editor, range }) => {
                    // Convert the current block to Heading 1.
                  },
                },
                {
                  title: 'Heading 2',
                  searchTerms: ['h2', 'heading2'],
                  command: ({ editor, range }) => {
                    // Convert the current block to Heading 2.
                  },
                },
              ],
            },
          ],
        },
      ]}
    />
  6. Extend Editor Functionality with Extensions

    main

    Use the extensions prop to add custom functionality. You can use MailyKit.configure for built-in features, VariableExtension.extend to customize variable views, or pass your own custom extensions.

    import { MailyKit, VariableExtension, getVariableSuggestions } from '@maily-to/core/extensions';
    
    <Editor
      extensions={[
        MailyKit.configure({
          linkCard: false,
        }),
        VariableExtension.extend({
          addNodeView() {
            return ReactNodeViewRenderer(VariableView, {
              className: 'mly:relative mly:inline-block',
              as: 'div',
            });
          },
        }).configure({
          suggestion: getVariableSuggestions(variableTriggerCharacter),
        }),
      ]}
    />
  7. Configure Variables and Auto-suggestions

    main

    Variables can be configured via the VariableExtension. You can provide variables as a static array of objects or as a dynamic function.

    • Array approach: Maily handles filtering based on the query automatically.
    • Function approach: You must handle the filtering logic yourself. The function receives query, from (context like repeat or variable), and the editor instance.

    Variables can be made optional by setting required: false.

    import { VariableExtension, getVariableSuggestions } from '@maily-to/core/extensions';
    
    // Using a function for dynamic variables
    <Editor
      extensions={[
        VariableExtension.configure({
          suggestion: getVariableSuggestions('@'),
          variables: ({ query, from, editor }) => {
            if (from === 'repeat-variable') {
              return [
                { name: 'notifications' },
                { name: 'comments' },
              ];
            }
    
            return [
              { name: 'currentDate' },
              { name: 'currentTime', required: false },
              {
                name: 'first_name',
                required: false,
                hideDefaultValue: true,
              },
            ];
          },
        }),
      ]}
    />
  8. Create Custom Rendered Blocks

    main

    You can render custom UI for a slash command by providing a render function to the block object. The render function receives the editor instance and should return a React element or null if nothing should be rendered.

    <Editor
      blocks={[
        {
          title: 'Custom Blocks',
          commands: [
            {
              title: 'Custom Block',
              searchTerms: ['custom'],
              render: (editor) => {
                return <div>Custom Block</div>;
              },
            },
          ],
        },
      ]}
    />
  9. Basic Usage of the Editor component

    main

    To use the @maily-to/core Editor, import the component and its required CSS. The Editor component accepts contentJson for initial content and provides onCreate and onUpdate callbacks to manage the editor instance (which is a Tiptap editor instance).

    import '@maily-to/core/style.css';
    
    import { useState } from 'react';
    import { Editor } from '@maily-to/core';
    import type { Editor as TiptapEditor, JSONContent } from '@tiptap/core';
    
    type AppProps = {
      contentJson: JSONContent;
    };
    
    function App(props: AppProps) {
      const { contentJson: defaultContentJson } = props;
      const [editor, setEditor] = useState<TiptapEditor>();
    
      return (
        <Editor
          contentJson={defaultContentJson}
          onCreate={setEditor}
          onUpdate={setEditor}
        />
      );
    }