Avatar Upload Example

A simple example demonstrating LiveTemplate's file upload feature with avatar upload functionality.

Features

What This Example Demonstrates

Upload Configuration

func (s *ProfileStore) AllowUploads() map[string]livetemplate.UploadConfig {
    return map[string]livetemplate.UploadConfig{
        "avatar": {
            Accept:      []string{"image/jpeg", "image/png", "image/gif"},
            MaxFileSize: 5 * 1024 * 1024, // 5MB
            MaxEntries:  1,                // Single file
            AutoUpload:  false,            // Manual upload on form submit
            ChunkSize:   256 * 1024,       // 256KB chunks
        },
    }
}

Upload Processing

func (s *ProfileStore) ConsumeUpload(ctx context.Context, name string, entries []*livetemplate.UploadEntry) error {
    for _, entry := range entries {
        // Move from temp to permanent location
        permanentPath := filepath.Join("uploads", fmt.Sprintf("avatar-%s%s", entry.ID, ext))
        os.Rename(entry.TempPath, permanentPath)

        // Update store with new avatar
        s.AvatarPath = permanentPath
        s.AvatarURL = "/" + permanentPath
    }
    return nil
}

Template Helpers

<input type="file" lvt-upload="avatar" accept="image/jpeg,image/png,image/gif">

<!-- Show upload progress -->
{{range .lvt.Uploads "avatar"}}
    <div class="upload-entry">
        <span>{{.ClientName}} - {{.Progress}}%</span>
        <progress value="{{.Progress}}" max="100"></progress>
        {{if .Error}}<span class="error">{{.Error}}</span>{{end}}
    </div>
{{end}}

Running the Example

1. Install Dependencies

cd /Users/adnaan/code/livetemplate/examples/avatar-upload
go mod download

2. Run the Server

go run main.go

The server will start at http://localhost:8080

3. Try It Out

  1. Open http://localhost:8080 in your browser
  2. Click "Choose File" and select an image (JPEG, PNG, or GIF)
  3. Click "Save Profile"
  4. Watch the real-time progress bar as your file uploads
  5. See your avatar appear instantly when upload completes!

Upload Strategies

This example uses WebSocket Chunked Upload:

File Structure

avatar-upload/
├── main.go              # Server code with ProfileStore
├── avatar-upload.tmpl   # HTML template with upload UI
├── go.mod              # Dependencies (uses local livetemplate)
├── README.md           # This file
└── uploads/            # Created at runtime for uploaded avatars

Testing Different Scenarios

Valid Upload

File Too Large

Invalid File Type

Multiple Files

Code Quality

This example demonstrates:

Next Steps

Want to extend this example?

  1. Add S3 Upload: Replace local storage with S3 presigner
  2. Multiple Avatars: Change MaxEntries to allow multiple images
  3. Image Cropping: Add client-side cropping before upload
  4. Drag & Drop: Add drag-and-drop file selection
  5. Auto-Upload: Set AutoUpload: true for instant uploads

Learn More

Troubleshooting

Upload not working?

Progress not updating?

Files not saving?


Built with ❤️ using LiveTemplate v0.3.0