# Discourse AI - Web Artifacts

**URL:** https://meta.discourse.org/t/discourse-ai-web-artifacts/339972
**Category:** Site Management
**Tags:** ai
**Created:** [December 3, 2024, 2:36am UTC](https://meta.discourse.org/t/discourse-ai-web-artifacts/339972 "2024-12-03T02:36:29Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [December 3, 2024, 2:36am UTC](https://meta.discourse.org/t/discourse-ai-web-artifacts/339972/1 "2024-12-03T02:36:29Z")

</div>

### **What Are AI Artifacts?**

AI Artifacts are powerful tools that allow users to create, embed, and interact with dynamic web-based components directly within a Discourse post. These components can contain custom **HTML** , **CSS** , and **JavaScript** , enabling a variety of use cases such as:

- Embedding interactive quizzes or forms.
- Visualizing data with rich graphics and animations.
- Integrating lightweight web applications or tools.
- A tool for learning about web frameworks, JavaScript libraries and more.

AI Artifacts seamlessly enhance Discourse posts by adding interactivity while ensuring a secure browsing experience.

* * *

### **Site Settings**

Administrators can configure several settings:

#### **1. Enabling the Feature**

- **Setting** : `discourse_ai_enabled`
  - Ensure this global setting is enabled for AI Artifacts to function.

#### **2. Security Modes**

- **Setting** : `ai_artifact_security`
  - Options:
    - `disabled`: Disable the artifact system
    - `lax`: Artifacts automatically appear in posts without requiring user interaction.
    - `hybrid`: Artifacts require a click to run by default, but post authors can add `data-ai-artifact-autorun` to the embed markup to make specific artifacts run immediately.
    - `strict`: Users must explicitly activate artifacts in their browser by clicking a “View” or “Run” button. This setting is recommended for security-conscious environments. (default)

#### **3. Artifact Creator Access**

- By default, the **Artifact Creator agent** is **restricted to staff users only**. This restriction ensures that only trusted individuals can create artifacts, minimizing the risk of improper or malicious usage.
- If broader access is required, permissions need to be manually configured by a site administrator.

* * *

### **Using AI Artifacts in Posts**

Artifacts are automatically created by the Artifact Creator agent on demand.

The above artifact was generated using GPT-4o and the anime.js library

Once created they are private to you and the Artifact Creator agent. Users who are able to share ai conversations (those who belong to the `ai bot public sharing allowed groups`) can also make an artifact public by sharing the conversation.

Once shared you can use the following HTML markup to render it in a post:

`<div class="ai-artifact" data-ai-artifact-version="3" data-ai-artifact-id="71"></div>`

(where the version and artifact id are your versioned artifact)

### **Security Considerations**

Given that AI Artifacts can execute custom-written HTML, CSS, and JavaScript, Discourse has implemented robust safeguards:

#### **1. Sandboxing in iFrames**

- Artifacts are rendered inside isolated `iframe` containers with `sandbox` attributes to restrict potentially unsafe operations like:
  - Cross-site scripting.
  - Access to external sites or APIs.

#### **2. Content Security Policy (CSP)**

- All resources in artifacts (like JavaScript libraries) are restricted to secure, pre-approved domains, such as:
- [https://cdn.jsdelivr.net](https://cdn.jsdelivr.net)
- [https://cdnjs.cloudflare.com](https://cdnjs.cloudflare.com)
- [https://unpkg.com](https://unpkg.com)
- [https://ajax.googleapis.com](https://ajax.googleapis.com)
- [https://d3js.org](https://d3js.org)
- [https://code.jquery.com](https://code.jquery.com)
- [https://esm.sh](https://esm.sh)

#### **3. Security Mode**

- **Strict Mode** : This is recommended for environments where artifacts are not fully trusted. Users will need to manually activate artifacts in their browser before they are rendered.

#### **4. Access and Permissions**

- Artifacts are visible only to:
  - Their creator.
  - Users with the right permissions to view the associated post (e.g., personal messages).

- Public artifacts must be explicitly marked as such by sharing the AI conversation.

#### **5. Length Limits**

- The size of HTML, CSS, and JavaScript in an artifact is capped at 64 KB each. This ensures components remain lightweight and do not burden users or systems.

### Artifact storage

Web artifacts can optionally store **per user** data. To do so hint the artifact creator with “use user storage” or similar.

This system allows storing key,value pairs:

- Private (only visible to admins and specific users)
- Public (visible to all users including anonymous)

Key value pairs are secured against the post the artifact originated from, however if you share an artifact publicly all will be allowed to add keys.

To control storage you can use the hidden settings:

- `ai_artifact_kv_value_max_length` (default items may only be 5000 letters or shorter)
- `ai_artifact_max_keys_per_user_per_artifact` (default 100)

### **FAQ**

#### **Who Can Create AI Artifacts?**

By default, only **staff users** (e.g., admins or moderators) can create artifacts through the **Artifact Creator Agent**. This agent simplifies the process of designing interactive web widgets using HTML, CSS, and JavaScript.

#### **What Happens If I Click an Artifact?**

- In **lax** mode, artifacts appear automatically.
- In **hybrid** mode, artifacts require a click by default, but can auto-run if the embed includes `data-ai-artifact-autorun`.
- In **strict** mode, clicking the “Run” button activates the artifact and allows it to load in your browser.

#### **Are AI Artifacts Safe?**

Yes. AI Artifacts run in tightly controlled environments:

- They are sandboxed and cannot interact with the Discourse application or user context directly, only via iframe messaging.
- The strict mode gives you control over activation.
- Artifacts are private by default you need to actively share to give global access.

### **Can I see the source code for Artifacts**

Yes. When Discourse AI generates artifacts it will include the full markup, css and JavaScript.

### **What LLMs are supported?**

Artifacts can be generated using any LLM you have configured, however various LLMs specialize and are more finely tuned for artifact creation.

We have seen good results with o3, Anthropic Claude Sonnet 3.7 - 4.0, GPT-4.1, Gemini Pro 2.5 and more. Generally more advanced models will do better.

There is a large aspect of trial and error with artifact creation, experimentation is key.

---

<div class="post-metadata">

### Author: ![MachineScholar](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/machinescholar/32/424719_2.png) [@MachineScholar](https://meta.discourse.org/u/MachineScholar)
#### Post date: [June 13, 2025, 8:18am UTC](https://meta.discourse.org/t/discourse-ai-web-artifacts/339972/3 "2025-06-13T08:18:26Z")

</div>

It’d be really neat to have slightly more granular control over artifact privacy so that they can be shared only with certain groups. Quite similar to how category permissions currently work 😃

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [June 13, 2025, 8:21am UTC](https://meta.discourse.org/t/discourse-ai-web-artifacts/339972/4 "2025-06-13T08:21:00Z")

</div>

I think that if you add the group to the bot pm it may work?

---

<div class="post-metadata">

### Author: ![MachineScholar](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/machinescholar/32/424719_2.png) [@MachineScholar](https://meta.discourse.org/u/MachineScholar)
#### Post date: [June 13, 2025, 8:23am UTC](https://meta.discourse.org/t/discourse-ai-web-artifacts/339972/5 "2025-06-13T08:23:00Z")

</div>

I’m gonna test it out and report back here. I have a niche use case that requires artifacts to be accessible only to one group in one private category

---

<div class="post-metadata">

### Author: ![MachineScholar](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/machinescholar/32/424719_2.png) [@MachineScholar](https://meta.discourse.org/u/MachineScholar)
#### Post date: [June 13, 2025, 6:58pm UTC](https://meta.discourse.org/t/discourse-ai-web-artifacts/339972/6 "2025-06-13T18:58:11Z")

</div>

> [@sam](#):
>
> add the group

So I tagged the Web Artifact Creator bot in a new topic in a private category which the group has access so it can make an artifact only viewable to me and that particular group. However the artifact iframe window only shows that default " Oops! That page doesn’t exist or is private." that pops up when a user doesn’t have access to a particular page

So I made a [data explorer](https://meta.discourse.org/t/32566?silent=true) query to check who could view that topic and the users in that group that _should be able to_ see the artifact are indeed shown to be able to view it according to the database.

So perhaps this is a bug?

> **My SQL query**
>
> ```sql
> -- [params]
> -- int :artifact_id = 22
> 
> WITH artifact_info AS (
> SELECT 
> a.id,
> a.user_id as creator_id,
> a.post_id,
> p.topic_id,
> t.category_id,
> t.archetype,
> c.read_restricted,
> t.title as topic_title
> FROM ai_artifacts a
> LEFT JOIN posts p ON a.post_id = p.id
> LEFT JOIN topics t ON p.topic_id = t.id
> LEFT JOIN categories c ON t.category_id = c.id
> WHERE a.id = :artifact_id
> ),
> users_with_access AS (
> -- Creator always has access
> SELECT 
> ai.creator_id as user_id,
> 'Creator' as access_reason
> FROM artifact_info ai
>   
> UNION
>   
> -- Users with access to private messages
> SELECT 
> tau.user_id,
> 'Private Message Access' as access_reason
> FROM artifact_info ai
> JOIN topic_allowed_users tau ON ai.topic_id = tau.topic_id
> WHERE ai.archetype = 'private_message'
>   
> UNION
>   
> -- Group members with access to private messages
> SELECT 
> gu.user_id,
> 'Private Message Group Access' as access_reason
> FROM artifact_info ai
> JOIN topic_allowed_groups tag ON ai.topic_id = tag.topic_id
> JOIN group_users gu ON tag.group_id = gu.group_id
> WHERE ai.archetype = 'private_message'
>   
> UNION
>   
> -- Users with access to restricted categories
> SELECT 
> gu.user_id,
> 'Category Group Access' as access_reason
> FROM artifact_info ai
> JOIN category_groups cg ON ai.category_id = cg.category_id
> JOIN group_users gu ON cg.group_id = gu.group_id
> WHERE ai.read_restricted = true
> AND ai.archetype != 'private_message'
> AND cg.permission_type IN (1, 2) -- full access or create/reply/see
>   
> UNION
>   
> -- All users if topic is public (not restricted and not private message)
> SELECT 
> u.id as user_id,
> 'Public Access' as access_reason
> FROM artifact_info ai
> CROSS JOIN users u
> WHERE (ai.read_restricted = false OR ai.read_restricted IS NULL)
> AND (ai.archetype != 'private_message' OR ai.archetype IS NULL)
> AND u.active = true
> )
> 
> SELECT 
> u.id as user_id,
> u.username,
> u.name,
> u.trust_level,
> uwa.access_reason,
> ai.topic_title
> FROM users_with_access uwa
> JOIN users u ON uwa.user_id = u.id
> CROSS JOIN artifact_info ai
> WHERE u.active = true
> ORDER BY u.username
> 
> ```
