---
title: "Artifact surface"
description: "Artifact surface sở hữu phần body của side panel bền vững. Khai báo artifactKind ổn định có namespace của app; Core dùng nó để resolve native module hiện tại trong app lane khi…"
url: "https://sotaagents.ai/vi/manual/developer-guide/artifact-surfaces"
generated_by: "sotaagents-ldp"
docs_index: "https://sotaagents.ai/manual/llms.txt"
locale: "vi"
---

# Artifact surface

Artifact surface sở hữu phần body của side panel bền vững. Khai báo `artifactKind` ổn định có namespace của app; Core dùng nó để resolve native module hiện tại trong app lane khi app mở artifact.

YAML

```
contributes:
  ui:
    - id: report-viewer
      kind: nativeModule
      surface: artifact
      slot: artifact.slot.reports-viewer
      artifactKind: reports.viewer
      module:
        entry: dist/ui/app.js
        export: ReportViewer
        styles: dist/ui/app.css
```

TSX

```
import { useAppContext } from '@sota/platform';

type ArtifactProps = {
  artifact: { artifactKind: string; context?: Record<string, unknown> };
};

export function ReportViewer({ artifact }: ArtifactProps) {
  const { ui } = useAppContext();
  const title = typeof artifact.context?.title === 'string'
    ? artifact.context.title
    : 'Report';
  return (
    <article>
      <h1>{title}</h1>
      <button type="button" onClick={ui.closeArtifact}>Close</button>
    </article>
  );
}
```

Mở từ surface trong cùng app lane bằng `useAppContext().ui.openArtifact('reports.viewer', context)`. Bản app hiện tại của lane render dữ liệu opaque trong `artifact.context`; app tự chịu trách nhiệm tương thích với payload do bản cũ tạo ra. Artifact kind phải duy nhất trong workspace đã resolve; namespace `core.*` được dành riêng.

TSX

```
import { useAppContext } from '@sota/platform';

export function OpenReportButton({ reportId }: { reportId: string }) {
  const { ui } = useAppContext();
  return <button type="button" onClick={() => ui.openArtifact('reports.viewer', {
    reportId, title: 'Quarterly report',
  })}>Open report</button>;
}
```

Validate `artifact.context` trước khi dùng; đây là transport data có cấu trúc, không thay thế việc load record có authority từ app backend.
