curl and Terminal Clients
curl, Wget, HTTPie and xh get a page's first frame as truecolor ANSI text. Configure its size or turn it off.
Các HTTP client trong terminal nhận frame đầu tiên của trang dưới dạng văn bản ANSI truecolor thay vì tài liệu HTML. Bạn không cần cấu hình gì.
curl https://my-app.example.com/aboutNhững yêu cầu nhận frame
Một yêu cầu nhận frame khi đáp ứng tất cả điều kiện sau:
- phương thức là
GEThoặcHEAD; User-Agentbắt đầu bằngcurl/,Wget/,wget2/,HTTPie/hoặcxh/;- không có header
Accepthoặc header này không chứatext/html.
Trình duyệt, trình thu thập dữ liệu và bản xem trước liên kết nhận trang HTML. Để nhận HTML từ curl, yêu cầu rõ định dạng này:
curl -H 'Accept: text/html' https://my-app.example.com/aboutFrame được chọn tại thời điểm trang sẽ được phục vụ: sau middleware, rewrites và route handler, và không bao giờ áp dụng cho tệp hoặc đường dẫn có dấu chấm trong đoạn cuối. Chuyển hướng, mã 401, header và rewrite của middleware áp dụng cho curl giống như với trình duyệt. /api/health vẫn chạy handler của nó và /robots.txt vẫn phục vụ tệp.
Nội dung trong frame
Frame là lần render đầu tiên của trang, giống như trong một shell được prerender: mỗi ranh giới <Suspense> còn đang chờ đều hiển thị fallback. Component máy chủ bất đồng bộ không chạy, và fetch() không bao giờ hoàn tất, nên dữ liệu tải trong effect vẫn ở trạng thái đang tải.
- Kích thước: 80 × 24 ô. Ứng dụng có viewport cố định (
viewport.responsive: false) dùngviewport.width × viewport.heightthay thế. - Màu sắc: mã thoát SGR 24-bit theo
viewport.themecủa ứng dụng. Mỗi dòng kết thúc bằng mã đặt lại, và frame kết thúc bằng ký tự xuống dòng. - Trạng thái:
200, hoặc404kèm trang không tìm thấy của ứng dụng khi không có trang nào khớp hoặc trang gọinotFound(). Trang gọiredirect()trong lúc render sẽ phục vụ HTML.
Phản hồi có kiểu text/plain; charset=utf-8 với Vary: User-Agent, Accept và Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate, nên bộ nhớ đệm dùng chung không bao giờ lưu frame rồi phục vụ nó cho trình duyệt. Trang HTML tại đường dẫn mà curl nhận frame cũng có cùng header Vary.
Môi trường hỗ trợ
| Môi trường lưu trữ | Trang tĩnh | Trang động, đường dẫn chưa biết |
|---|---|---|
text dev | Render khi có yêu cầu | Render khi có yêu cầu |
text start, bun | Prerender bằng text build | Render khi có yêu cầu |
vercel, cloudflare | Prerender bằng text build | Trang HTML |
static | Trang HTML | Trang HTML |
Trang được render phía máy chủ cần text start hoặc bun (xem Triển khai).
Môi trường lưu trữ tĩnh không thể trả lời khác nhau cho từng client, nên adapter static không hỗ trợ frame. Trên Vercel và Cloudflare, frame cho trang tĩnh đi kèm bản build. Trang động ([id], force-dynamic) phục vụ HTML tại đó, vì adapter vercel và cloudflare không triển khai trình render.
text start và bun dist/server.js render những trang còn lại khi có yêu cầu bằng .text/server/live.mjs, và giữ 128 frame gần nhất trong 10 giây. Mỗi máy chủ render tối đa 20 trang chưa có trong bộ nhớ đệm mỗi 10 giây. Khi vượt mức đó, curl nhận trang HTML cho đến khi hạn mức được khôi phục. Nếu máy chủ không thể tải live.mjs, chẳng hạn vì một mô-đun trang đọc window ở cấp cao nhất, những trang đó sẽ phục vụ HTML.
text build báo cáo các frame đã prerender:
✓ Prerendering curl frames (5/5)Cấu hình
Đổi kích thước cho toàn bộ ứng dụng, hoặc tắt frame:
import { defineConfig } from "@textjs/app";export default defineConfig({ ansi: { cols: 100, rows: 30 }, // ansi: false,});Một trang có thể đổi kích thước riêng, hoặc phục vụ HTML cho cả terminal:
export const ansi = { cols: 120, rows: 40 };// export const ansi = false;Kích thước được giới hạn trong khoảng 1–500 ô. Khi đặt ansi: false trong text.config.ts, các export của trang sẽ bị bỏ qua.
HTTP thuần
curl không theo chuyển hướng trừ khi bạn truyền -L. Vercel chuyển hướng yêu cầu http:// sang https://, và Cloudflare cũng vậy khi bật Luôn sử dụng HTTPS, nên curl http://… in ra chuyển hướng thay vì frame. Chia sẻ URL https://.
Máy chủ tùy chỉnh
@textjs/app/ansi export các hàm hỗ trợ nhận diện và phản hồi, dành cho máy chủ và hàm không chạy text start hoặc adapter:
import { ansiResponse, wantsAnsi } from "@textjs/app/ansi";import { frameToAnsi } from "@textjs/react";if (wantsAnsi(request)) return ansiResponse(frameToAnsi(buffer, { theme: "geistDark" }), request.method);wantsAnsi(request) cũng nhận (method, headers) với Headers của Web hoặc IncomingHttpHeaders của Node. frameToAnsi(buffer, { theme }) mã hóa một CellBuffer đã render theo cùng cách với framework.