mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-25 09:06:34 +01:00
⛓️💥 fix: Replace React Markdown Artifact Renderer with Static HTML (#12337)
Some checks are pending
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
Some checks are pending
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
The react-markdown dependency chain uses Node.js subpath imports (vfile/lib/#minpath) that Sandpack's bundler cannot resolve, breaking markdown artifact preview. Switch to a self-contained static HTML page using marked.js from CDN, eliminating the React bootstrap overhead and the problematic dependency resolution.
This commit is contained in:
parent
59873e74fc
commit
b66f7914a5
4 changed files with 224 additions and 198 deletions
|
|
@ -19,7 +19,7 @@ describe('useArtifactProps', () => {
|
|||
const { result } = renderHook(() => useArtifactProps({ artifact }));
|
||||
|
||||
expect(result.current.fileKey).toBe('content.md');
|
||||
expect(result.current.template).toBe('react-ts');
|
||||
expect(result.current.template).toBe('static');
|
||||
});
|
||||
|
||||
it('should handle text/plain type with content.md as fileKey', () => {
|
||||
|
|
@ -31,7 +31,7 @@ describe('useArtifactProps', () => {
|
|||
const { result } = renderHook(() => useArtifactProps({ artifact }));
|
||||
|
||||
expect(result.current.fileKey).toBe('content.md');
|
||||
expect(result.current.template).toBe('react-ts');
|
||||
expect(result.current.template).toBe('static');
|
||||
});
|
||||
|
||||
it('should include content.md in files with original markdown', () => {
|
||||
|
|
@ -46,7 +46,7 @@ describe('useArtifactProps', () => {
|
|||
expect(result.current.files['content.md']).toBe(markdownContent);
|
||||
});
|
||||
|
||||
it('should include App.tsx with wrapped markdown renderer', () => {
|
||||
it('should include index.html with static markdown rendering', () => {
|
||||
const artifact = createArtifact({
|
||||
type: 'text/markdown',
|
||||
content: '# Test',
|
||||
|
|
@ -54,8 +54,8 @@ describe('useArtifactProps', () => {
|
|||
|
||||
const { result } = renderHook(() => useArtifactProps({ artifact }));
|
||||
|
||||
expect(result.current.files['App.tsx']).toContain('MarkdownRenderer');
|
||||
expect(result.current.files['App.tsx']).toContain('import React from');
|
||||
expect(result.current.files['index.html']).toContain('<!DOCTYPE html>');
|
||||
expect(result.current.files['index.html']).toContain('marked.parse');
|
||||
});
|
||||
|
||||
it('should include all required markdown files', () => {
|
||||
|
|
@ -66,12 +66,8 @@ describe('useArtifactProps', () => {
|
|||
|
||||
const { result } = renderHook(() => useArtifactProps({ artifact }));
|
||||
|
||||
// Check all required files are present
|
||||
expect(result.current.files['content.md']).toBeDefined();
|
||||
expect(result.current.files['App.tsx']).toBeDefined();
|
||||
expect(result.current.files['index.tsx']).toBeDefined();
|
||||
expect(result.current.files['/components/ui/MarkdownRenderer.tsx']).toBeDefined();
|
||||
expect(result.current.files['markdown.css']).toBeDefined();
|
||||
expect(result.current.files['index.html']).toBeDefined();
|
||||
});
|
||||
|
||||
it('should escape special characters in markdown content', () => {
|
||||
|
|
@ -82,13 +78,11 @@ describe('useArtifactProps', () => {
|
|||
|
||||
const { result } = renderHook(() => useArtifactProps({ artifact }));
|
||||
|
||||
// Original content should be preserved in content.md
|
||||
expect(result.current.files['content.md']).toContain('`const x = 1;`');
|
||||
expect(result.current.files['content.md']).toContain('C:\\Users');
|
||||
|
||||
// App.tsx should have escaped content
|
||||
expect(result.current.files['App.tsx']).toContain('\\`');
|
||||
expect(result.current.files['App.tsx']).toContain('\\\\');
|
||||
expect(result.current.files['index.html']).toContain('\\`');
|
||||
expect(result.current.files['index.html']).toContain('\\\\');
|
||||
});
|
||||
|
||||
it('should handle empty markdown content', () => {
|
||||
|
|
@ -112,7 +106,7 @@ describe('useArtifactProps', () => {
|
|||
expect(result.current.files['content.md']).toBe('# No content provided');
|
||||
});
|
||||
|
||||
it('should provide react-markdown dependency', () => {
|
||||
it('should have no custom dependencies for markdown (uses CDN)', () => {
|
||||
const artifact = createArtifact({
|
||||
type: 'text/markdown',
|
||||
content: '# Test',
|
||||
|
|
@ -120,9 +114,8 @@ describe('useArtifactProps', () => {
|
|||
|
||||
const { result } = renderHook(() => useArtifactProps({ artifact }));
|
||||
|
||||
expect(result.current.sharedProps.customSetup?.dependencies).toHaveProperty('react-markdown');
|
||||
expect(result.current.sharedProps.customSetup?.dependencies).toHaveProperty('remark-gfm');
|
||||
expect(result.current.sharedProps.customSetup?.dependencies).toHaveProperty('remark-breaks');
|
||||
const deps = result.current.sharedProps.customSetup?.dependencies ?? {};
|
||||
expect(deps).toEqual({});
|
||||
});
|
||||
|
||||
it('should update files when content changes', () => {
|
||||
|
|
@ -137,7 +130,6 @@ describe('useArtifactProps', () => {
|
|||
|
||||
expect(result.current.files['content.md']).toBe('# Original');
|
||||
|
||||
// Update the artifact content
|
||||
const updatedArtifact = createArtifact({
|
||||
...artifact,
|
||||
content: '# Updated',
|
||||
|
|
@ -201,8 +193,6 @@ describe('useArtifactProps', () => {
|
|||
|
||||
const { result } = renderHook(() => useArtifactProps({ artifact }));
|
||||
|
||||
// Language parameter should not affect markdown handling
|
||||
// It checks the type directly, not the key
|
||||
expect(result.current.fileKey).toBe('content.md');
|
||||
expect(result.current.files['content.md']).toBe('# Test');
|
||||
});
|
||||
|
|
@ -214,7 +204,6 @@ describe('useArtifactProps', () => {
|
|||
|
||||
const { result } = renderHook(() => useArtifactProps({ artifact }));
|
||||
|
||||
// Should use default behavior
|
||||
expect(result.current.template).toBe('static');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue