ActiveCanvas Documentation

Complete reference for installing, configuring, and extending ActiveCanvas — the open-source CMS engine for Rails 8+.

Installation

Add ActiveCanvas to your Gemfile:

gem "active_canvas"

Then run the install generator:

bundle install
bin/rails generate active_canvas:install
bin/rails db:migrate

The interactive installer will:

  • Copy and run database migrations
  • Create config/initializers/active_canvas.rb with configuration options
  • Mount the engine in your routes (default: /canvas)
  • Prompt you to choose a CSS framework (Tailwind, Bootstrap 5, or none)
  • Optionally configure AI API keys

Once the installer finishes, visit /canvas/admin to start building pages.

Quick Start

Get a page live in five steps:

  1. Go to /canvas/admin — open the admin dashboard
  2. Create a Page Type — for example, "Landing Page" or "Blog Post"
  3. Create a Page — give it a title and slug, then click Editor to open the visual builder
  4. Build your page — drag blocks onto the canvas, use AI to generate content, upload images from the media library
  5. Publish — your page is immediately live at /canvas/your-slug

Configuration

All configuration lives in config/initializers/active_canvas.rb. Below is the complete reference of every option, grouped by category.

Authentication

Option Default Description
authenticate_admin nil Method name (symbol), :http_basic_auth, or a lambda. Controls access to the admin interface.
authenticate_public nil Same options as above. nil means public pages are accessible without authentication.
current_user_method :current_user Method name used for version tracking and AI feature attribution.
admin_parent_controller nil Set to a controller class name (string) to inherit authentication from your app.
public_parent_controller nil Same as above, for public-facing page controllers.

CSS Framework

Option Default Description
css_framework :tailwind Choose :tailwind, :bootstrap5, or :none.

Media Uploads

Option Default Description
enable_uploads true Enable or disable file uploads entirely.
max_upload_size 10.megabytes Maximum allowed file size for uploads.
allow_svg_uploads false SVG uploads are disabled by default for security.
storage_service nil Active Storage service name. nil uses the default service.
public_uploads false false serves files via signed URLs; true uses public URLs.

Editor

Option Default Description
enable_ai_features true Toggle AI content generation in the editor.
enable_code_editor true Show the inline HTML/CSS code editor panel.
enable_asset_manager true Show the media library inside the editor.
autosave_interval 60 Seconds between auto-saves. Set to 0 to disable.

Pages

Option Default Description
max_versions_per_page 50 Maximum version history entries per page. Set to 0 for unlimited.

Security

Option Default Description
sanitize_content true Sanitize page HTML content on save.
ai_rate_limit_per_minute 30 Maximum AI requests allowed per minute per user.

Full Example

# config/initializers/active_canvas.rb
ActiveCanvas.configure do |config|
  # Authentication
  config.authenticate_admin = :authenticate_user!
  config.authenticate_public = nil
  config.current_user_method = :current_user

  # CSS Framework
  config.css_framework = :tailwind

  # Media Uploads
  config.enable_uploads = true
  config.max_upload_size = 10.megabytes
  config.allow_svg_uploads = false
  config.storage_service = nil
  config.public_uploads = false

  # Editor
  config.enable_ai_features = true
  config.enable_code_editor = true
  config.enable_asset_manager = true
  config.autosave_interval = 60

  # Pages
  config.max_versions_per_page = 50

  # Security
  config.sanitize_content = true
  config.ai_rate_limit_per_minute = 30
end

Authentication

The admin interface is open by default. Configure authentication before deploying to production. ActiveCanvas supports four approaches.

1. Devise

If your app uses Devise, point authenticate_admin to the Devise helper method:

ActiveCanvas.configure do |config|
  config.authenticate_admin = :authenticate_user!
end

2. Custom Controller

Inherit from a controller that already handles authentication:

ActiveCanvas.configure do |config|
  config.admin_parent_controller = "Admin::ApplicationController"
end

All ActiveCanvas admin controllers will inherit from the specified controller, picking up its before_action filters, layout, and helper methods.

3. HTTP Basic Auth

Simple password protection without a user model:

ActiveCanvas.configure do |config|
  config.authenticate_admin = :http_basic_auth
  config.http_basic_user = "admin"
  config.http_basic_password = Rails.application.credentials.active_canvas_password
end

4. Lambda

For completely custom logic, pass a lambda that runs in the controller context:

ActiveCanvas.configure do |config|
  config.authenticate_admin = -> {
    unless current_user&.admin?
      redirect_to main_app.root_path, alert: "Access denied"
    end
  }
end

CSS Framework

ActiveCanvas supports three CSS framework options:

  • :tailwind — Tailwind CSS v4. Uses the CDN in the editor for instant live preview. On save, compiles only the CSS classes used on that page. Public pages serve compiled CSS inline with zero CDN dependency.
  • :bootstrap5 — Bootstrap 5 loaded via CDN in the editor and on public pages.
  • :none — No framework. Write vanilla CSS or bring your own.

Tailwind Setup

For production-grade Tailwind compilation, add the tailwindcss-ruby gem:

gem "tailwindcss-ruby", ">= 4.0"

Then set the framework in your initializer:

ActiveCanvas.configure do |config|
  config.css_framework = :tailwind
end

That is all the setup required. CSS compiles automatically when pages are saved. If the gem is not installed, ActiveCanvas falls back to serving the Tailwind CDN on public pages.

You can customize the Tailwind theme (colors, fonts, spacing) from the admin settings panel, and trigger a bulk recompile of all pages when the theme changes.

AI Setup

ActiveCanvas uses RubyLLM to provide AI-powered content generation directly in the editor. Supported capabilities:

Feature Description Supported Models
Chat Generate and edit HTML content with streaming GPT-4o, Claude Sonnet 4, Claude 3.5 Haiku
Image Generation Create images from text prompts DALL-E 3, GPT Image 1
Screenshot to Code Upload a screenshot, get production-ready HTML/CSS GPT-4o, Claude Sonnet 4 (vision models)

API Keys

Configure keys via environment variables or Rails credentials in your initializer:

# config/initializers/active_canvas.rb
Rails.application.config.after_initialize do
  # Via environment variables
  ActiveCanvas::Setting.ai_openai_api_key = ENV["OPENAI_API_KEY"]
  ActiveCanvas::Setting.ai_anthropic_api_key = ENV["ANTHROPIC_API_KEY"]
  ActiveCanvas::Setting.ai_openrouter_api_key = ENV["OPENROUTER_API_KEY"]

  # Or via Rails credentials
  credentials = Rails.application.credentials.active_canvas || {}
  ActiveCanvas::Setting.ai_openai_api_key = credentials[:openai_api_key]
end

You can also configure API keys from the admin UI at /canvas/admin/settings (AI tab).

Sync Models

After setting your API keys, sync the available models:

bin/rails active_canvas:sync_models

Or use the Sync Models button on the admin settings page. This fetches the list of available models from each configured provider.

Server Timeout

AI requests — especially image generation and screenshot-to-code — can take longer than typical web requests. If you run Puma in clustered mode, increase the worker timeout:

# config/puma.rb
worker_timeout 180

Or set the environment variable:

PUMA_WORKER_TIMEOUT=180

If you are behind a reverse proxy (Nginx, Apache), also increase its read timeout for the ActiveCanvas routes:

# Nginx example
location /canvas {
  proxy_read_timeout 180s;
  proxy_send_timeout 180s;
}

Media Library

Upload and manage images directly from the admin dashboard or from within the editor's built-in asset manager.

Supported Formats

  • Images: JPEG, PNG, GIF, WebP, AVIF
  • Documents: PDF
  • Vector: SVG (disabled by default — enable with config.allow_svg_uploads = true)

Storage

Media files are stored through Active Storage, so any backend works: local disk, Amazon S3, Google Cloud Storage, or Azure Blob Storage. Set config.storage_service to the name of your Active Storage service, or leave it as nil to use the default.

URL Mode

  • config.public_uploads = false — serves files via signed, expiring URLs (default)
  • config.public_uploads = true — serves files via permanent public URLs

File Size

The maximum upload size defaults to 10 MB. Change it with:

config.max_upload_size = 25.megabytes

Page Versioning

Every content change creates a version automatically. View the version history from the page admin panel to see:

  • What changed — visual before/after diffs of the HTML content
  • Who made the change — attributed via your current_user_method
  • When it was made — timestamped for auditing
  • Content size differences — see how much was added or removed

Roll back to any previous version with a single click.

Configuring Retention

By default, ActiveCanvas keeps the last 50 versions per page. Adjust with:

config.max_versions_per_page = 100  # keep more history
config.max_versions_per_page = 0    # unlimited (no pruning)

When the limit is reached, the oldest versions are automatically pruned on each new save.

Customization

Mount Path

By default the engine mounts at /canvas. Change it in your routes:

# config/routes.rb
mount ActiveCanvas::Engine => "/pages"    # or "/cms", "/blog", "/"

Override Views

Copy any ActiveCanvas view into your application to customize its markup. Rails will prefer your local copy over the engine's default:

app/views/active_canvas/pages/show.html.erb
app/views/active_canvas/admin/pages/index.html.erb
app/views/layouts/active_canvas/admin/application.html.erb

Extend Models

Add validations, scopes, or methods to ActiveCanvas models using class_eval:

ActiveCanvas::Page.class_eval do
  validates :content, presence: true

  def excerpt
    content.to_s.truncate(200)
  end
end

Place model extensions in an initializer or in config/initializers/active_canvas_extensions.rb so they load on boot.

Rake Tasks

ActiveCanvas ships with two rake tasks for managing AI model availability:

Task Description
active_canvas:sync_models Fetches the latest available models from all configured AI providers (OpenAI, Anthropic, OpenRouter) and stores them in the database.
active_canvas:list_models Lists all synced AI models with their provider, type, and status.

Usage

bin/rails active_canvas:sync_models    # Sync AI models from configured providers
bin/rails active_canvas:list_models    # List all synced AI models

Run sync_models after adding or changing API keys, or periodically via a scheduled job to keep the model list up to date.