### Install ActiveCanvas and Run Migrations
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
After adding the gem, run the install generator, which will copy migrations, mount the engine, and configure the CSS framework. Then, migrate the database and start the server.
```bash
bundle install
bin/rails generate active_canvas:install
# Interactive wizard: copies migrations, mounts engine, chooses CSS framework, configures AI keys
bin/rails db:migrate
bin/rails server
# Admin available at http://localhost:3000/canvas/admin
```
--------------------------------
### Clone and Setup Active Canvas
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Steps to clone the Active Canvas repository, install dependencies, migrate the database, and run tests for local development.
```bash
git clone https://github.com/giovapanasiti/active_canvas.git
cd active_canvas
bundle install
bin/rails db:migrate
bin/rails test
```
--------------------------------
### Install Migrations
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Copies engine migrations to the host application.
```APIDOC
## Rake Task: Install Migrations
### Description
Copies engine migrations to the host application.
### Command
```bash
bin/rails active_canvas:install:migrations
```
```
--------------------------------
### Start Active Canvas Development Server
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Command to start the Rails server for Active Canvas development and the URL to access the admin interface.
```bash
bin/rails server
```
--------------------------------
### Run ActiveCanvas Install Generator
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Execute the install generator to set up ActiveCanvas in your Rails application. This will run migrations, create initializer files, mount the engine, and prompt for CSS framework selection.
```bash
bundle install
bin/rails generate active_canvas:install
```
--------------------------------
### Get AI Model Lists for Editor
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Facade service to retrieve model lists, falling back to defaults if the database is empty.
```ruby
ActiveCanvas::AiModels.text_models # => Array of hashes (from DB or defaults)
ActiveCanvas::AiModels.image_models # => Array of hashes
ActiveCanvas::AiModels.vision_models # => Array of hashes
```
--------------------------------
### Low-Level Setting Get/Set
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Perform low-level get and set operations for custom settings. Use `set` to store a value and `get` to retrieve it.
```ruby
ActiveCanvas::Setting.set("my_custom_key", "my_value")
ActiveCanvas::Setting.get("my_custom_key") # => "my_value"
```
--------------------------------
### Install ActiveCanvas Migrations
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Run this Rake task to copy the engine's migrations to your host application, allowing you to manage them with your application's migration system.
```bash
bin/rails active_canvas:install:migrations
```
--------------------------------
### Configure Admin Authentication with Custom Logic
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Implement custom authentication logic for the admin interface using a lambda function. This example denies access to non-admin users.
```ruby
ActiveCanvas.configure do |config|
config.authenticate_admin = -> {
unless current_user&.admin?
redirect_to main_app.root_path, alert: "Access denied"
end
}
end
```
--------------------------------
### Full Active Canvas Configuration
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
A comprehensive example of Active Canvas configuration options, covering authentication, CSS framework, media uploads, editor settings, page versioning, and security.
```ruby
# config/initializers/active_canvas.rb
ActiveCanvas.configure do |config|
# === Authentication ===
config.authenticate_admin = :authenticate_user! # method name, lambda, or :http_basic_auth
config.authenticate_public = nil # nil = public access
config.current_user_method = :current_user # for version tracking & AI features
# === CSS Framework ===
config.css_framework = :tailwind # :tailwind, :bootstrap5, or :none
# === Media Uploads ===
config.enable_uploads = true
config.max_upload_size = 10.megabytes
config.allow_svg_uploads = false
config.storage_service = nil # Active Storage service name
config.public_uploads = false # false = signed URLs
# === Editor ===
config.enable_ai_features = true
config.enable_code_editor = true
config.enable_asset_manager = true
config.autosave_interval = 60 # seconds (0 = disabled)
# === Pages ===
config.max_versions_per_page = 50 # 0 = unlimited
# === Security ===
config.sanitize_content = true
config.ai_rate_limit_per_minute = 30
end
```
--------------------------------
### Install ActiveCanvas Gem
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Add the ActiveCanvas gem to your Gemfile to include it in your Rails application.
```ruby
gem "active_canvas"
```
--------------------------------
### Page Scopes and Instance Methods
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Provides examples of using scopes to filter pages by status and accessing instance methods to retrieve rendered content or version information. Use `ActiveCanvas::Page.current_editor` to track edits for version history.
```ruby
# Scopes
ActiveCanvas::Page.published # => all published pages
ActiveCanvas::Page.draft # => all draft pages
# Instance methods
page.rendered_content # => content.html_safe
page.current_version_number # => integer (latest version number)
page.show_header? # => true
page.show_footer? # => true
# Track who edited for version history
ActiveCanvas::Page.current_editor = "admin@example.com"
page.update!(content: "
Updated!
")
# A PageVersion is automatically created with before/after diff
# Programmatic content update with version attribution
ActiveCanvas::Page.current_editor = current_user.email
page.update!(content: new_html, content_css: new_css)
```
--------------------------------
### Settings API - Update AI Settings
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Updates AI-related settings, such as the OpenAI API key. The API key is skipped if blank or starts with '****'.
```APIDOC
## PATCH /canvas/admin/settings/update_ai
### Description
Updates AI-related settings, such as the OpenAI API key. The API key is skipped if blank or starts with '****'.
### Method
`PATCH`
### Endpoint
`/canvas/admin/settings/update_ai`
### Parameters
#### Request Body
- **ai_openai_api_key** (String) - The OpenAI API key.
### Request Example
```json
{
"ai_openai_api_key": "sk-..."
}
```
```
--------------------------------
### Sync AI Models with Rails Command
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
After configuring API keys, run this command to sync available AI models with your ActiveCanvas setup. This can also be done via the admin UI.
```bash
bin/rails active_canvas:sync_models
```
--------------------------------
### Extend Active Canvas Models
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Example of extending the `ActiveCanvas::Page` model to add custom validations and methods, such as an `excerpt` method.
```ruby
ActiveCanvas::Page.class_eval do
validates :content, presence: true
def excerpt
content.to_s.truncate(200)
end
end
```
--------------------------------
### Update AI Settings
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
This endpoint allows for updating AI-related settings, such as API keys. The `ai_openai_api_key` is skipped if it's blank or starts with '****', ensuring sensitive information is not inadvertently exposed.
```json
# PATCH /canvas/admin/settings/update_ai
# {
# "ai_openai_api_key": "sk-...", # skipped if blank or starts with "****"
# }
```
--------------------------------
### Retrieve Media URL
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Get the URL for a media record. The URL is signed by default but can be public if `config.public_uploads` is true. `public_url` provides the direct public URL for cloud storage.
```ruby
# Retrieve URL (signed by default, public if config.public_uploads = true)
media.url # => "/rails/active_storage/blobs/redirect/..." or signed URL
media.public_url # => direct public URL for cloud storage
```
--------------------------------
### Create and Publish a Page
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Demonstrates creating a new page with various attributes, including content, SEO metadata, and Open Graph tags. Ensure a PageType is created first. Content is automatically sanitized on save.
```ruby
# Create a page type first
landing = ActiveCanvas::PageType.find_or_create_by!(key: "landing") { |t| t.name = "Landing Page" }
blog = ActiveCanvas::PageType.find_or_create_by!(key: "blog") { |t| t.name = "Blog Post" }
# Create and publish a page
page = ActiveCanvas::Page.create!(
title: "Welcome to Our Site",
slug: "welcome", # auto-parameterized; auto-set if blank
page_type: landing,
published: true,
content: "
Hello!
",
show_header: true,
show_footer: true,
# SEO
meta_title: "Welcome | My Site",
meta_description: "The best place on the internet.",
canonical_url: "https://example.com/canvas/welcome",
meta_robots: "index,follow",
# Open Graph
og_title: "Welcome to Our Site",
og_description: "The best place.",
og_image: "https://example.com/og.png",
# Twitter Card
twitter_card: "summary_large_image",
# JSON-LD
structured_data: '{"@context":"https://schema.org","@type":"WebPage","name":"Welcome"}'
)
```
--------------------------------
### Create Custom Page Types
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Shows how to ensure default page types exist and how to create custom ones with specific keys and names. Custom types automatically generate a key from the name if not provided.
```ruby
# Ensure defaults exist
default_type = ActiveCanvas::PageType.default # finds or creates key: "page"
# Create custom types
ActiveCanvas::PageType.create!(name: "Blog Post") # key auto-set to "blog_post"
ActiveCanvas::PageType.create!(name: "Case Study", key: "case_study")
# List all pages of a type
case_study_type = ActiveCanvas::PageType.find_by(key: "case_study")
case_study_type.pages.published.order(created_at: :desc)
```
--------------------------------
### Configure AI API Keys in Initializer
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Set up your AI API keys within the `config/initializers/active_canvas.rb` file. You can use environment variables or Rails credentials. Ensure these keys are correctly configured for AI features to function.
```ruby
# 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
```
--------------------------------
### Admin Pages API - Get Editor Data
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Retrieves the editor data for a specific page, including its content, CSS, JavaScript, and component structure.
```APIDOC
## GET /canvas/admin/pages/:id/editor.json
### Description
Retrieves the editor data for a specific page, including its content, CSS, JavaScript, and component structure.
### Method
`GET`
### Endpoint
`/canvas/admin/pages/:id/editor.json`
### Response
- **content** (String) - The HTML content of the page.
- **content_css** (String) - Custom CSS for the page content.
- **content_js** (String) - Custom JavaScript for the page content.
- **content_components** (String) - JSON string representing page components.
### Response Example
```json
{ "content": "...", "content_css": "...", "content_js": "...", "content_components": "..." }
```
```
--------------------------------
### Access Page Version History
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Demonstrates how to access and iterate through a page's version history, including details like version number, editor, timestamp, changes, and size differences. It also shows how to inspect a specific version's diff.
```ruby
page = ActiveCanvas::Page.find(1)
# Access version history (most recent first)
page.versions.recent.limit(10).each do |v|
puts "v#{v.version_number} by #{v.changed_by} at #{v.created_at}"
puts v.changes_description # => "Changed: content, CSS"
puts v.size_difference_formatted # => "+1234 bytes" or "-200 bytes"
puts v.content_changed? # => true/false
puts v.css_changed? # => true/false
end
# Inspect a specific version's diff
version = page.versions.find_by(version_number: 3)
puts version.content_diff # unified-style line diff
# Rollback by applying a previous version's content
old_version = page.versions.find_by(version_number: 2)
ActiveCanvas::Page.current_editor = "rollback_script"
page.update!(content: old_version.content_after, content_css: old_version.css_after)
```
--------------------------------
### Query ActiveCanvas Pages from Host Application
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Demonstrates how to query `ActiveCanvas::Page` records from within a host application's controller, enabling hybrid content management scenarios.
```ruby
class BlogController < ApplicationController
def index
@posts = ActiveCanvas::Page
.published
.includes(:page_type)
.where(active_canvas_page_types: { key: "blog" })
.order(created_at: :desc)
.page(params[:page])
end
end
```
--------------------------------
### Configure Admin Authentication with HTTP Basic Auth
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Set up HTTP Basic Authentication for the admin interface, including specifying the username and password from Rails credentials.
```ruby
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
```
--------------------------------
### Settings API - Update Global CSS
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Updates the global CSS settings for the application.
```APIDOC
## PATCH /canvas/admin/settings/update_global_css
### Description
Updates the global CSS settings for the application.
### Method
`PATCH`
### Endpoint
`/canvas/admin/settings/update_global_css`
### Parameters
#### Request Body
- **global_css** (String) - The CSS string to apply globally.
### Request Example
```json
{ "global_css": "body { font-family: 'Inter'; }" }
```
### Response
#### Success Response (200)
- **success** (Boolean) - Indicates if the update was successful.
- **message** (String) - A confirmation message.
### Response Example
```json
{ "success": true, "message": "Global CSS saved." }
```
```
--------------------------------
### Generate Image with AI Service
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Create an image using `AiService.generate_image`. The generated image is saved to the media library and a `Media` record is returned. Specify the prompt and model.
```ruby
# --- Image generation (saves to Media library, returns Media record) ---
media = AiService.generate_image(
prompt: "A futuristic cityscape at sunset, digital art style",
model: "dall-e-3" # nil = Setting.ai_default_image_model
)
puts media.url # usable image URL stored in Active Storage
```
--------------------------------
### Manage Encrypted API Keys and Settings
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Illustrates how to set and retrieve API keys and other runtime settings using the `ActiveCanvas::Setting` model. API keys are automatically encrypted at rest. Use `*_configured?` and `masked_*` methods to check and display keys securely.
```ruby
# AI API Keys (encrypted at rest)
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"]
# Check configuration without exposing the value
ActiveCanvas::Setting.api_key_configured?("ai_openai_api_key") # => true/false
ActiveCanvas::Setting.masked_api_key("ai_openai_api_key") # => "****Ab1C"
# Default AI models
ActiveCanvas::Setting.ai_default_text_model = "gpt-4o"
ActiveCanvas::Setting.ai_default_image_model = "dall-e-3"
ActiveCanvas::Setting.ai_default_vision_model = "gpt-4o"
```
--------------------------------
### Set CSS Framework
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Specify the CSS framework to be used. This can be 'tailwind', 'bootstrap5', or 'custom'. This setting overrides the default configuration at runtime.
```ruby
ActiveCanvas::Setting.css_framework = "tailwind" # "tailwind" | "bootstrap5" | "custom"
```
--------------------------------
### Query Media Scopes
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Utilize scopes like `images`, `recent`, and `limit` for efficient querying of media assets, particularly for paginated display in an asset manager.
```ruby
# Scopes
ActiveCanvas::Media.images.recent.limit(20) # paginated in the editor asset manager
```
--------------------------------
### Sync AI Models from Providers
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Import or update AI model records from configured providers using RubyLLM. This populates the database for model selection in the editor.
```ruby
count = ActiveCanvas::AiModel.refresh_from_ruby_llm!
# => 47 (number of models imported/updated)
```
--------------------------------
### ActiveCanvas Settings
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Configuration options for AI features, CSS framework, global assets, homepage, and Tailwind theme.
```APIDOC
## ActiveCanvas Settings
### AI Feature Toggles
- `ActiveCanvas::Setting.ai_text_enabled`
- `ActiveCanvas::Setting.ai_image_enabled`
- `ActiveCanvas::Setting.ai_screenshot_enabled`
### CSS Framework
- `ActiveCanvas::Setting.css_framework = "tailwind"` (Options: "tailwind", "bootstrap5", "custom")
### Global CSS/JS
- `ActiveCanvas::Setting.global_css = "..."`
- `ActiveCanvas::Setting.global_js = "..."`
### Homepage
- `ActiveCanvas::Setting.homepage_page_id = `
- `ActiveCanvas::Setting.homepage`
### Tailwind Theme Customization
- `ActiveCanvas::Setting.tailwind_config = { ... }`
- `ActiveCanvas::Setting.tailwind_config_js`
### Low-level Get/Set
- `ActiveCanvas::Setting.set("key", "value")`
- `ActiveCanvas::Setting.get("key")`
```
--------------------------------
### Check AI Configuration Status
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Verify if any AI providers are configured and check feature enablement.
```ruby
ActiveCanvas::AiConfiguration.configured?
ActiveCanvas::AiConfiguration.configured_providers
ActiveCanvas::AiConfiguration.text_enabled?
ActiveCanvas::AiConfiguration.image_enabled?
ActiveCanvas::AiConfiguration.screenshot_enabled?
```
--------------------------------
### ActiveCanvas::AiModels Service
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
A facade that provides lists of AI models for the editor, with fallback to default models when the database is empty.
```APIDOC
## ActiveCanvas::AiModels Service
Facade that returns model lists for the editor, falling back to hardcoded defaults when the database is empty.
```ruby
ActiveCanvas::AiModels.text_models # => Array of hashes (from DB or defaults)
ActiveCanvas::AiModels.image_models # => Array of hashes
ActiveCanvas::AiModels.vision_models # => Array of hashes
ActiveCanvas::AiModels.models_synced? # => true/false
ActiveCanvas::AiModels.last_synced_at # => Time or nil
ActiveCanvas::AiModels.refresh! # triggers AiModel.refresh_from_ruby_llm!
# Default fallback models (used when DB is empty):
# Text: gpt-4o, gpt-4o-mini, claude-sonnet-4-20250514, claude-3-5-haiku-20241022
# Image: dall-e-3, gpt-image-1
# Vision: gpt-4o, gpt-4o-mini, claude-sonnet-4-20250514
```
```
--------------------------------
### List Synced AI Models
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Lists all active AI models that have been synced into the database, categorized by type (Text/Chat, Image).
```bash
bin/rails active_canvas:list_models
```
--------------------------------
### Upload Media File
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Create a new media record and attach a file using Active Storage. This typically occurs via the admin UI or a REST endpoint. The file type is validated, dangerous MIME types are blocked, and size limits are enforced.
```ruby
media = ActiveCanvas::Media.new(filename: "hero.png")
media.file.attach(
io: File.open("/path/to/hero.png"),
filename: "hero.png",
content_type: "image/png"
)
media.save!
```
--------------------------------
### AI Model Instance Helpers
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Access details and properties of individual AI model records.
```ruby
model = ActiveCanvas::AiModel.find_by(model_id: "gpt-4o")
model.display_name # => "GPT-4o"
model.supports_vision? # => true
model.price_info # => "$5.0/M in / $15.0/M out"
model.as_json_for_editor
# => { id: "gpt-4o", name: "GPT-4o", provider: "openai", type: "chat",
# input_modalities: ["text","image"], output_modalities: ["text"],
# supports_functions: true, context_window: 128000, max_tokens: 16384 }
```
--------------------------------
### Configure RubyLLM
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Force re-configuration of RubyLLM, typically called automatically before AI requests.
```ruby
ActiveCanvas::AiConfiguration.configure_ruby_llm!
```
--------------------------------
### ActiveCanvas::AiConfiguration
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Manages API keys and configures RubyLLM for AI operations. It provides methods to check configuration status and feature enablement.
```APIDOC
## ActiveCanvas::AiConfiguration
Reads API keys from `Setting` and configures RubyLLM. Used internally before every AI call.
```ruby
# Check if any provider is configured
ActiveCanvas::AiConfiguration.configured? # => true/false
# Which providers have keys set
ActiveCanvas::AiConfiguration.configured_providers # => ["openai", "anthropic"]
# Feature-level checks (configured AND feature toggle enabled)
ActiveCanvas::AiConfiguration.text_enabled? # => true/false
ActiveCanvas::AiConfiguration.image_enabled? # => true/false
ActiveCanvas::AiConfiguration.screenshot_enabled? # => true/false
# Force reconfigure RubyLLM (called automatically before each AI request)
ActiveCanvas::AiConfiguration.configure_ruby_llm!
```
```
--------------------------------
### Configure Admin Parent Controller
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Set a custom parent controller for the admin interface if you are using a different controller hierarchy.
```ruby
ActiveCanvas.configure do |config|
config.admin_parent_controller = "Admin::ApplicationController"
end
```
--------------------------------
### Inject Global CSS and JavaScript
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Define global CSS styles and JavaScript code to be injected on every public page. This is useful for site-wide styling and behavior.
```ruby
ActiveCanvas::Setting.global_css = "body { font-family: 'Inter', sans-serif; }"
ActiveCanvas::Setting.global_js = "console.log('ActiveCanvas site loaded');"
```
--------------------------------
### Settings API - Update Global JavaScript
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Updates the global JavaScript settings for the application.
```APIDOC
## PATCH /canvas/admin/settings/update_global_js
### Description
Updates the global JavaScript settings for the application.
### Method
`PATCH`
### Endpoint
`/canvas/admin/settings/update_global_js`
### Parameters
#### Request Body
- **global_js** (String) - The JavaScript string to apply globally.
### Request Example
```json
{ "global_js": "window.analytics = {};" }
```
### Response
#### Success Response (200)
- **success** (Boolean) - Indicates if the update was successful.
- **message** (String) - A confirmation message.
### Response Example
```json
{ "success": true, "message": "Global JavaScript saved." }
```
```
--------------------------------
### Media JSON Representation for Editor
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Generate a JSON representation of a media record suitable for use in an editor interface. Includes ID, source URL, name, type, width, and height.
```ruby
# Editor JSON representation
media.as_json_for_editor
# => { id: 1, src: "/rails/...", name: "hero.png", type: "image/png",
# width: 1920, height: 1080 }
```
--------------------------------
### ActiveCanvas::AiModel Model
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Represents a persisted catalog of AI models synced from providers. It tracks model capabilities, pricing, and context window, used to populate editor dropdowns.
```APIDOC
## ActiveCanvas::AiModel Model
Persisted catalog of AI models synced from providers via RubyLLM. Tracks modalities (text input, image input, text output, image output), pricing, and context window. The editor uses these records to populate model selector dropdowns.
```ruby
# Sync from all configured providers
count = ActiveCanvas::AiModel.refresh_from_ruby_llm!
# => 47 (number of models imported/updated)
# Convenience scopes
ActiveCanvas::AiModel.active.text_models.order(:name)
ActiveCanvas::AiModel.active.image_models
ActiveCanvas::AiModel.active.vision_models # text+image input, text output
ActiveCanvas::AiModel.active.for_provider("openai")
# Instance helpers
model = ActiveCanvas::AiModel.find_by(model_id: "gpt-4o")
model.display_name # => "GPT-4o"
model.supports_vision? # => true
model.price_info # => "$5.0/M in / $15.0/M out"
model.as_json_for_editor
# => { id: "gpt-4o", name: "GPT-4o", provider: "openai", type: "chat",
# input_modalities: ["text","image"], output_modalities: ["text"],
# supports_functions: true, context_window: 128000, max_tokens: 16384 }
# Toggle model availability (shown/hidden in editor dropdowns)
model.update!(active: false)
# Rake task equivalents
# bin/rails active_canvas:sync_models — full sync from all configured providers
# bin/rails active_canvas:list_models — print models to stdout
```
```
--------------------------------
### Page CRUD Operations (HTML)
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Standard RESTful routes for managing pages, including index, new, create, show, edit, update, and delete. The index action provides media statistics, and the update action allows modification of various page attributes.
```ruby
# Page CRUD (HTML-only):
# GET /canvas/admin/pages -> index with media stats
# GET /canvas/admin/pages/new
# POST /canvas/admin/pages -> create
# GET /canvas/admin/pages/:id
# GET /canvas/admin/pages/:id/edit
# PATCH /canvas/admin/pages/:id -> update (title, slug, SEO, publish status, etc.)
# DELETE /canvas/admin/pages/:id
# GET /canvas/admin/pages/:id/versions -> version history list
# Permitted params for PATCH/POST:
# title, slug, content, page_type_id, published, show_header, show_footer,
# meta_title, meta_description, canonical_url, meta_robots,
# og_title, og_description, og_image,
# twitter_card, twitter_title, twitter_description, twitter_image,
# structured_data
```
--------------------------------
### Manage ActiveCanvas Partials
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
This code demonstrates how to ensure default partials exist, retrieve active header and footer, update their content programmatically, and manage their active status. The `update!` method automatically recompiles Tailwind CSS if `tailwindcss-ruby` is available.
```ruby
# Ensure both partials exist (called by the engine initializer)
ActiveCanvas::Partial.ensure_defaults!
# Retrieve
header = ActiveCanvas::Partial.active_header # header with active: true
footer = ActiveCanvas::Partial.active_footer
# Update content programmatically
header.update!(content: "")
# Tailwind CSS is compiled automatically after_save if tailwindcss-ruby is available
# Rendered output
header.rendered_content # => content.html_safe
header.full_css # => compiled_css + "\n" + content_css
# Activate / deactivate
header.update!(active: false) # header won't render on public pages
# Admin routes for editing partials:
# GET /canvas/admin/partials -> index
# GET /canvas/admin/partials/:id/editor -> visual GrapeJS editor
# PATCH /canvas/admin/partials/:id/save_editor -> save editor content
```
--------------------------------
### ActiveCanvas::Media Model
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Handles media uploads, storage, and retrieval, including URL generation and editor integration.
```APIDOC
## ActiveCanvas::Media Model
### Upload File
```ruby
media = ActiveCanvas::Media.new(filename: "hero.png")
media.file.attach(
io: File.open("/path/to/hero.png"),
filename: "hero.png",
content_type: "image/png"
)
media.save!
```
### Retrieve URL
- `media.url` (Signed by default)
- `media.public_url` (Direct public URL)
### Editor JSON Representation
- `media.as_json_for_editor`
### Scopes
- `ActiveCanvas::Media.images.recent.limit(20)`
### REST API
#### List Media
`GET /canvas/admin/media.json?page=1&per_page=20`
Response:
```json
{
"data": [...as_json_for_editor...],
"meta": {
"current_page": 1,
"per_page": 20,
"total_count": 100,
"total_pages": 5
}
}
```
#### Upload Media
`POST /canvas/admin/media` (multipart)
Request Body:
```json
{
"media": {
"file": "",
"filename": "photo.jpg"
}
}
```
Response (201):
```json
{
"id": 1,
"src": "...",
"name": "photo.jpg",
"type": "image/jpeg",
"width": 1920,
"height": 1080
}
```
#### Delete Media
`DELETE /canvas/admin/media/:id`
Response (204): No Content
```
--------------------------------
### Query Active AI Models
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Retrieve AI models based on their status, provider, and modality. Useful for populating editor dropdowns.
```ruby
ActiveCanvas::AiModel.active.text_models.order(:name)
ActiveCanvas::AiModel.active.image_models
ActiveCanvas::AiModel.active.vision_models # text+image input, text output
ActiveCanvas::AiModel.active.for_provider("openai")
```
--------------------------------
### Configure Tailwind Theme
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Define the Tailwind theme, including colors and fonts, via `Setting.tailwind_config`. These settings are used during compilation.
```ruby
ActiveCanvas::Setting.tailwind_config = {
theme: { extend: { colors: { brand: "#6366f1" }, fontFamily: { sans: ["Inter"] } } }
}
# brand color and Inter font will be injected as @theme variables during compilation
```
--------------------------------
### Active Canvas Rake Tasks
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
List of available Rake tasks for Active Canvas, including syncing and listing AI models.
```bash
bin/rails active_canvas:sync_models # Sync AI models from configured providers
bin/rails active_canvas:list_models # List all synced AI models
```
--------------------------------
### List AI Models
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Lists all active synced AI models, categorized by type (Text/Chat, Image, Vision).
```APIDOC
## Rake Task: List AI Models
### Description
Lists all active synced AI models, categorized by type.
### Command
```bash
bin/rails active_canvas:list_models
```
### Output Example
```
=== Text/Chat Models ===
anthropic Claude 3.5 Haiku
anthropic Claude Sonnet 4 [vision]
openai GPT-4o [vision]
...
=== Image Models ===
openai DALL-E 3
openai GPT Image 1
Total: 34 models
```
```
--------------------------------
### Configure ActiveCanvas Settings
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Centralize ActiveCanvas configurations in `config/initializers/active_canvas.rb`. This block controls authentication methods, CSS framework, media upload settings, editor features, versioning limits, and AI security parameters.
```ruby
# config/initializers/active_canvas.rb
ActiveCanvas.configure do |config|
# === Authentication ===
# Option A: Devise method name
config.authenticate_admin = :authenticate_user!
# Option B: Custom lambda with admin check
config.authenticate_admin = -> {
redirect_to main_app.root_path, alert: "Access denied" unless current_user&.admin?
}
# Option C: Inherit from existing admin controller
config.admin_parent_controller = "Admin::ApplicationController"
# Option D: HTTP Basic Auth (good for staging)
config.authenticate_admin = :http_basic_auth
config.http_basic_user = "admin"
config.http_basic_password = Rails.application.credentials.active_canvas_password
# Public pages: nil = no auth required
config.authenticate_public = nil
config.current_user_method = :current_user # for version tracking & AI features
# === CSS Framework ===
config.css_framework = :tailwind # :tailwind | :bootstrap5 | :none
# === Media Uploads ===
config.enable_uploads = true
config.max_upload_size = 10.megabytes
config.allow_svg_uploads = false # disabled by default (XSS risk)
config.storage_service = :amazon # nil = default Active Storage service
config.public_uploads = false # false = signed URLs with 1h expiry
# === Editor ===
config.enable_ai_features = true
config.enable_code_editor = true
config.enable_asset_manager = true
config.autosave_interval = 60 # seconds; 0 = disabled
# === Versioning ===
config.max_versions_per_page = 50 # 0 = unlimited
# === Security ===
config.sanitize_content = true
config.ai_rate_limit_per_minute = 30
config.ai_stream_timeout = 5.minutes
config.ai_stream_idle_timeout = 30.seconds
config.ai_max_response_size = 1.megabyte
end
```
--------------------------------
### Mount ActiveCanvas Engine in Routes
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Mount the ActiveCanvas engine in your application's `config/routes.rb` file to define its base path. The engine automatically handles all its sub-routes.
```ruby
# config/routes.rb
Rails.application.routes.draw do
# Default mount path
mount ActiveCanvas::Engine => "/canvas"
# Alternative mount paths
# mount ActiveCanvas::Engine => "/cms"
# mount ActiveCanvas::Engine => "/blog"
# mount ActiveCanvas::Engine => "/"
end
# Routes provided by the engine:
# GET /canvas/admin -> admin pages index
# GET /canvas/admin/pages -> list all pages
# GET /canvas/admin/pages/new -> new page form
# GET /canvas/admin/pages/:id/editor -> GrapeJS visual editor
# GET /canvas/admin/media -> media library
# GET /canvas/admin/settings -> settings (general, styles, AI, models tabs)
# POST /canvas/admin/ai/chat -> SSE streaming text generation
# POST /canvas/admin/ai/image -> image generation
# POST /canvas/admin/ai/screenshot_to_code -> screenshot → HTML
# GET /canvas/admin/ai/models -> list configured AI models
# GET /canvas/admin/ai/status -> AI configuration status
# GET /canvas/:slug -> public page by slug
```
--------------------------------
### Convert Screenshot to Code with AI Service
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Transform base64-encoded image data into HTML code using `AiService.screenshot_to_code`. This method accepts image data, an optional model, and additional prompts for customization.
```ruby
# --- Screenshot to code ---
# image_data = Base64-encoded data URL: "data:image/png;base64,xFFFF"
html = AiService.screenshot_to_code(
image_data: "data:image/png;base64,iVBORw0KGgo...",
model: "gpt-4o", # nil = Setting.ai_default_vision_model
additional_prompt: "Use Bootstrap 5 grid system"
)
puts html # => "
...
"
```
--------------------------------
### Generate Text with AI Service
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Stream text content using the `AiService.generate_text` method. This is typically called from an SSE controller. Specify the prompt, model, and optional context. The content is streamed in chunks.
```ruby
# --- Text generation (streaming, called from the SSE controller) ---
AiService.generate_text(
prompt: "Create a hero section for a SaaS product called CloudSync",
model: "gpt-4o", # nil = Setting.ai_default_text_model
context: "Generate a complete page section or component."
) do |chunk|
puts chunk.content # streamed partial HTML
end
```
--------------------------------
### ActiveCanvas::Partial Model
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Manages singleton header and footer records that are edited visually and auto-compile Tailwind CSS. Public pages render the active header/footer unless explicitly hidden.
```APIDOC
## ActiveCanvas::Partial Model
### Description
Manages singleton header and footer records that are edited visually and auto-compile Tailwind CSS. Public pages render the active header/footer unless explicitly hidden.
### Methods
#### `ensure_defaults!`
Ensures that default header and footer partials exist. This is called by the engine initializer.
```ruby
ActiveCanvas::Partial.ensure_defaults!
```
#### `active_header`
Retrieves the currently active header partial.
```ruby
header = ActiveCanvas::Partial.active_header
```
#### `active_footer`
Retrieves the currently active footer partial.
```ruby
footer = ActiveCanvas::Partial.active_footer
```
#### `update!(attributes)`
Updates the content of a partial programmatically. Tailwind CSS is compiled automatically after save if `tailwindcss-ruby` is available.
```ruby
header.update!(content: "")
```
#### `rendered_content`
Returns the rendered HTML content of the partial.
```ruby
header.rendered_content # => content.html_safe
```
#### `full_css`
Returns the compiled CSS for the partial, including any custom CSS.
```ruby
header.full_css # => compiled_css + "\n" + content_css
```
#### `update!(active: false)`
Deactivates a partial, so it won't render on public pages.
```ruby
header.update!(active: false)
```
### Admin Routes
- `GET /canvas/admin/partials`
- `GET /canvas/admin/partials/:id/editor`
- `PATCH /canvas/admin/partials/:id/save_editor`
```
--------------------------------
### Bulk Toggle AI Models
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Perform bulk actions (like deactivation) on AI models based on scope and provider. This is useful for managing multiple models efficiently.
```http
POST /canvas/admin/settings/bulk_toggle_ai_models
{
"action_type": "deactivate",
"scope": "chat",
"provider": "openai"
}
```
--------------------------------
### Mount Active Canvas Engine
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Mount the Active Canvas engine in your application's routes file, specifying the desired mount path.
```ruby
# config/routes.rb
mount ActiveCanvas::Engine => "/pages" # or "/cms", "/blog", "/"
```
--------------------------------
### Retrieve Page Editor Content (JSON)
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
This endpoint fetches the current content, CSS, JavaScript, and component data for a specific page, typically used to load the GrapeJS editor with existing page information.
```json
# GET /canvas/admin/pages/:id/editor.json
# => { "content": "...", "content_css": "...", "content_js": "...", "content_components": "..." }
```
--------------------------------
### Override Active Canvas Views
Source: https://github.com/giovapanasiti/active_canvas/blob/master/README.md
Instructions on how to override default Active Canvas views by copying them into your application's view directory.
```text
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
```
--------------------------------
### Update Global CSS Setting
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
This JSON endpoint allows for updating the global CSS configuration for the application. It's used to apply site-wide styles that are not tied to specific pages or components.
```json
# PATCH /canvas/admin/settings/update_global_css (JSON)
# { "global_css": "body { font-family: 'Inter'; }" }
# => { "success": true, "message": "Global CSS saved." }
```
--------------------------------
### Compile Tailwind CSS for HTML Content
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Compile raw HTML content using Tailwind CSS v4. The output is minified CSS. Requires the `tailwindcss-ruby` gem.
```ruby
css = ActiveCanvas::TailwindCompiler.compile(
"
Hello
",
identifier: "my-snippet" # used in log messages only
)
# => "*, :before, :after{...} .flex{display:flex} .items-center{...} ..." (minified)
```
--------------------------------
### Recompile Tailwind CSS
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Queues pages for Tailwind CSS recompilation. This is useful after updating the Tailwind configuration.
```APIDOC
## POST /canvas/admin/settings/recompile_tailwind
### Description
Queues pages for Tailwind CSS recompilation.
### Method
POST
### Endpoint
/canvas/admin/settings/recompile_tailwind
### Response
#### Success Response (200)
- **success** (boolean) - Indicates if the operation was successful.
- **count** (integer) - The number of pages queued for compilation.
- **message** (string) - A message confirming the compilation queue.
#### Response Example
```json
{
"success": true,
"count": 12,
"message": "Queued 12 pages for compilation."
}
```
```
--------------------------------
### Sync AI Models
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Synchronizes AI models from all configured providers into the database. This operation can be performed via the API or a Rake task.
```APIDOC
## POST /canvas/admin/settings/sync_ai_models
### Description
Synchronizes AI models from all configured providers into the database.
### Method
POST
### Endpoint
/canvas/admin/settings/sync_ai_models
### Response
#### Success Response (200)
- **success** (boolean) - Indicates if the operation was successful.
- **count** (integer) - The number of models synced.
- **message** (string) - A message confirming the sync operation.
#### Response Example
```json
{
"success": true,
"count": 47,
"message": "Synced 47 models."
}
```
```
```APIDOC
## Rake Task: Sync AI Models
### Description
Sync AI models from all configured providers into the DB using a Rake task.
### Command
```bash
bin/rails active_canvas:sync_models
```
### Output Example
```
Configured providers: openai, anthropic
Syncing models...
Done! Synced 47 models.
Breakdown:
Text models: 31
Image models: 3
Vision models: 13
```
```
--------------------------------
### Set Homepage Page ID
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Assign a specific page ID to be used as the homepage. The homepage setting retrieves a published ActiveCanvas::Page object.
```ruby
ActiveCanvas::Setting.homepage_page_id = 5
ActiveCanvas::Setting.homepage # => ActiveCanvas::Page (published)
```
--------------------------------
### Bulk Toggle AI Models
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Performs a bulk action (activate or deactivate) on AI models based on specified criteria.
```APIDOC
## POST /canvas/admin/settings/bulk_toggle_ai_models
### Description
Performs a bulk action (activate or deactivate) on AI models based on specified criteria.
### Method
POST
### Endpoint
/canvas/admin/settings/bulk_toggle_ai_models
### Parameters
#### Request Body
- **action_type** (string) - Required - The action to perform (e.g., "deactivate", "activate").
- **scope** (string) - Optional - The scope of models to affect (e.g., "chat").
- **provider** (string) - Optional - The AI model provider (e.g., "openai").
### Request Example
```json
{
"action_type": "deactivate",
"scope": "chat",
"provider": "openai"
}
```
### Response
#### Success Response (200)
- **success** (boolean) - Indicates if the operation was successful.
- **count** (integer) - The number of models affected by the bulk action.
- **message** (string) - A message confirming the bulk action.
#### Response Example
```json
{
"success": true,
"count": 12,
"message": "Deactivated 12 models."
}
```
```
--------------------------------
### Add ActiveCanvas Gem to Gemfile
Source: https://context7.com/giovapanasiti/active_canvas/llms.txt
Include the ActiveCanvas gem and optionally the tailwindcss-ruby gem for runtime Tailwind CSS compilation in your Gemfile.
```ruby
# Gemfile
gem "active_canvas"
gem "tailwindcss-ruby", ">= 4.0" # optional — enables runtime Tailwind compilation
```