Certainly! You are correct that saving images as base64 within your WYSIWYG editor content is not recommended due to security, performance, and storage concerns. The best practice is to upload the image to your server (or a cloud storage service), then insert the image URL into the editor content.
Here’s a typical flow for handling image uploads with a WYSIWYG editor like Tiptap:
1. User selects an image in the editor.
2. The image is uploaded to your server via AJAX (e.g., using Axios or Fetch).
3. The server stores the image and returns the public URL.
4. The editor inserts the image using the returned URL.
Example Implementation
Frontend (Tiptap + Axios)
import { Editor } from '@tiptap/core'
import Image from '@tiptap/extension-image'
import axios from 'axios'
const editor = new Editor({
extensions: [
Image,
// ...other extensions
],
// ...other options
})
// Example function to handle image upload
async function uploadImage(file) {
const formData = new FormData()
formData.append('image', file)
const response = await axios.post('/api/images', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
return response.data.url // The URL returned by your backend
}
// Example: Handling image selection and insertion
document.querySelector('#image-input').addEventListener('change', async (event) => {
const file = event.target.files[0]
if (!file) return
const url = await uploadImage(file)
editor.chain().focus().setImage({ src: url }).run()
})
Backend (Laravel Example)
public function store(Request $request)
{
$request->validate([
'image' => 'required|image|max:2048', // 2MB Max
]);
$path = $request->file('image')->store('images', 'public');
return response()->json([
'url' => asset('storage/' . $path),
]);
}
HTML Example
<input type="file" id="image-input" accept="image/*" />
Summary
- Never store images as base64 in your database.
- Always upload images to your server or a storage service.
- Store only the image URL in your editor content.
- Use AJAX to handle uploads and update the editor with the returned URL.
This approach keeps your content lightweight, secure, and scalable.
Let me know if you need a more detailed example or help with a specific stack!