Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tiptap Php Laravel Package

ueberdosis/tiptap-php

PHP utilities for working with Tiptap: parse and validate ProseMirror/Tiptap JSON, render or transform documents, and build extensions-friendly pipelines on the backend. Ideal for Laravel apps needing server-side handling of rich-text editor content.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ueberdosis/tiptap-php
    

    Requires PHP 8.0+.

  2. First Use Case: Convert HTML to Tiptap JSON:

    use Tiptap\Editor;
    
    $editor = new Editor();
    $json = $editor->setContent('<p>Hello, Tiptap!</p>')->getJSON();
    

    Or JSON to HTML:

    $html = (new Editor())
        ->setContent(['type' => 'doc', 'content' => [...]])
        ->getHTML();
    

Where to Look First

  • Core Methods: setContent(), getHTML(), getJSON(), getText(), sanitize().
  • Extensions: StarterKit (default), CodeBlockHighlight, CodeBlockShiki, Link, etc.
  • Documentation: Tiptap.js API for conceptual understanding.

Implementation Patterns

Common Workflows

1. Content Conversion Pipeline

// HTML → JSON → Sanitized HTML → Plain Text
$editor = new Editor();
$json = $editor->setContent('<p>Unsafe <script>...</script></p>')->getJSON();
$sanitizedHtml = $editor->sanitize($json)->getHTML();
$plainText = $editor->getText(['blockSeparator' => "\n"]);

2. Custom Editor Configuration

$editor = new Editor([
    'extensions' => [
        new StarterKit([
            'heading' => ['levels' => [1, 2, 3]],
            'codeBlock' => false,
        ]),
        new CodeBlockShiki(['theme' => 'github-dark']),
        new Link(['openInNewTab' => true]),
    ],
]);

3. Dynamic Content Modification

$editor = new Editor();
$editor->setContent('<h1>Title</h1><p>Content</p>');

// Modify headings to level 2
$editor->descendants(function (&$node) {
    if ($node->type === 'heading') {
        $node->attrs->level = 2;
    }
});
$updatedHtml = $editor->getHTML();

4. Handling User Uploads (e.g., Images)

// Parse uploaded HTML (e.g., from CKEditor/TinyMCE)
$editor = new Editor();
$safeJson = $editor->sanitize($userUploadedHtml)->getJSON();

// Store JSON in DB, render later
$renderedHtml = (new Editor())->setContent($safeJson)->getHTML();

5. SEO Optimization (Plain Text Extraction)

$editor = new Editor();
$metaDescription = $editor
    ->setContent($articleHtml)
    ->getText(['blockSeparator' => ' ', 'ellipsis' => '...', 'length' => 160]);

Integration Tips

Laravel-Specific Patterns

  1. Service Provider Binding:

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton(Editor::class, function () {
            return new Editor([
                'extensions' => [
                    new StarterKit(),
                    new Link(),
                ],
            ]);
        });
    }
    
  2. Form Request Validation:

    // app/Http/Requests/StoreArticleRequest.php
    public function rules()
    {
        return [
            'content' => 'required|string|tiptap_json', // Custom rule for JSON validation
        ];
    }
    
  3. Blade Directives for Rendering:

    // app/Providers/BladeServiceProvider.php
    Blade::directive('tiptap', function ($expression) {
        return "<?php echo (new \\Tiptap\\Editor())->setContent({$expression})->getHTML(); ?>";
    });
    

    Usage:

    {!! tiptap($article->content) !!}
    
  4. API Response Formatting:

    return response()->json([
        'html' => $editor->setContent($request->json)->getHTML(),
        'text' => $editor->getText(),
    ]);
    

Performance Considerations

  • Reuse Editor Instances: Instantiate the editor once (e.g., as a singleton) and reuse it for multiple operations.
  • Cache Extensions: If using CodeBlockShiki, cache the Shiki instance to avoid reinitializing Node.js for each request.
  • Batch Processing: For bulk operations (e.g., updating many articles), process content in chunks to avoid memory issues.

Gotchas and Tips

Pitfalls

  1. Reference Handling in descendants():

    • Issue: Forgetting & in the callback parameter modifies a copy, not the original node.
    • Fix: Always use function (&$node) to modify nodes in-place.
      $editor->descendants(function (&$node) { ... }); // Correct
      $editor->descendants(function ($node) { ... });  // Incorrect (no effect)
      
  2. HTML Attribute Conflicts:

    • Issue: Custom HTML attributes (e.g., data-*) may conflict with Tiptap’s internal parsing.
    • Fix: Use HTMLAttributes in extension config to explicitly define allowed attributes.
      new Heading(['HTMLAttributes' => ['class' => 'my-heading']])
      
  3. Nested Marks:

    • Issue: Marks (e.g., bold + italic) may not render as expected due to DOM serialization quirks.
    • Fix: Use Mark extensions with parseHTML and renderHTML carefully. Test with complex nested cases.
      new Marks\Strong(['parseHTML' => ['strong', 'b']]);
      
  4. Shiki Dependency:

    • Issue: CodeBlockShiki requires Node.js and shiki npm package, which may not be available in shared hosting.
    • Fix: Fall back to CodeBlockHighlight or disable code blocks if Shiki is unavailable.
      try {
          new CodeBlockShiki();
      } catch (\RuntimeException $e) {
          new CodeBlockHighlight();
      }
      
  5. Schema Validation:

    • Issue: Invalid JSON/HTML may cause silent failures or malformed output.
    • Fix: Validate input before processing:
      if (!json_validate($request->content)) {
          throw new \InvalidArgumentException('Invalid Tiptap JSON');
      }
      
  6. Priority Collisions:

    • Issue: Custom nodes/marks with default priority (100) may override built-in extensions.
    • Fix: Adjust priority in your extension class:
      class CustomNode extends Node {
          public static $priority = 50; // Lower than default
      }
      

Debugging Tips

  1. Inspect Intermediate JSON:

    $json = $editor->setContent($html)->getJSON();
    \Log::debug('Tiptap JSON:', ['json' => json_encode($json, JSON_PRETTY_PRINT)]);
    
  2. Compare HTML Output: Use browser dev tools to compare rendered HTML with expected output. Look for:

    • Missing classes/attributes.
    • Incorrect nesting (e.g., <strong> inside <code>).
  3. Extension Isolation: Test extensions one by one to identify conflicts:

    // Test StarterKit alone
    $editor = new Editor(['extensions' => [new StarterKit()]]);
    
  4. Shiki Debugging: Enable Shiki logging to diagnose issues:

    new CodeBlockShiki(['debug' => true]);
    

Configuration Quirks

  1. StarterKit Shortcuts:

    • Disable individual features via array syntax:
      new StarterKit(['heading' => false, 'bulletList' => true])
      
    • Nested configurations (e.g., heading.levels) are supported but may not cover all JS API features.
  2. Default Extensions:

    • The editor auto-loads StarterKit. To disable it entirely:
      new Editor(['extensions' => []])
      
  3. Sanitization Scope:

    • sanitize() only removes malicious content (e.g., <script>). For stricter rules, combine with PHP’s filter_var() or HTML purifiers like HTMLPurifier.
  4. Plain Text Options:

    • getText() supports these options:
      • blockSeparator: String between blocks (default: \n\n).
      • ellipsis: Truncate long text (e.g., '...').
      • length: Max length for truncated text.

Extension Points

  1. Custom Nodes/Marks:

    • Extend Tiptap\Core\Node or Tiptap\Core\Mark for new content types.
    • Implement parseHTML(), renderHTML(), and addOptions() methods.
  2. Override Default Rendering:

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony