{"schemaVersion":1,"generatedAt":"2026-10-13T09:55:45.414Z","site":{"name":"Perxel","url":"https://perxel.com","description":"Perxel Studio, boutique tech studio lập trình website hiệu năng cao và sản phẩm AI. Đồng hành cùng designer, agency và doanh nghiệp, từ Core Web Vitals đến MCP server kết nối AI với dữ liệu thật.","founder":"Phúc Bùi","email":"hello@perxel.com","location":"Vietnam (serving clients worldwide)","specialties":"WordPress custom theme, custom plugin development, web animation (GSAP), responsive frontend, PageSpeed and Core Web Vitals, Next.js, AI products and integrations, MCP servers, React, Tailwind CSS","language":"Vietnamese at the root, English under /en"},"services":[{"kind":"service","locale":"vi","slug":"wordpress-custom-theme","title":"Lập trình WordPress Custom Theme","shortTitle":"WordPress Custom Theme","excerpt":"Boutique studio Perxel làm website WordPress bằng custom theme viết riêng, từ website doanh nghiệp đến cửa hàng online WooCommerce. Tải nhanh, dễ quản trị, bàn giao toàn bộ mã nguồn.","categories":["WordPress"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"nectarblocks","label":"NectarBlocks"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/services/wordpress-custom-theme","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Perxel làm website WordPress bằng custom theme viết riêng cho từng dự án, theo đúng bản thiết kế Figma của bạn. WordPress là hệ quản trị nội dung được dùng nhiều nhất hiện nay, theo số liệu của W3Techs. Doanh nghiệp làm chủ mã nguồn, dữ liệu và tự chọn hosting phù hợp.\n\nLàm chủ tài sản số\n\n- Làm chủ 100% dữ liệu. Khác với các nền tảng đóng dạng SaaS, nơi bạn trả phí subscription hệ thống định kỳ và chịu sự kiểm soát về mặt hạ tầng, WordPress cho phép doanh nghiệp sở hữu trọn vẹn mã nguồn, cơ sở dữ liệu và tự do lựa chọn đơn vị hosting phù hợp với ngân sách thực tế.\n- Khả năng thích ứng linh hoạt. Hệ sinh thái mở của WordPress giúp website dễ dàng tích hợp các công cụ marketing, hệ thống CRM, cổng thanh toán trực tuyến hoặc các giải pháp nội bộ khi doanh nghiệp mở rộng quy mô hoạt động.\n- Nền tảng tốt cho SEO. Kết hợp với Rank Math hoặc Yoast SEO, WordPress cho phép khai báo metadata, sitemap và dữ liệu có cấu trúc cho từng trang. Các website WordPress Perxel lập trình như Khatra Tile và Sundmd đều đạt 100 điểm SEO trên PageSpeed, xem thêm tại SEO và GEO cho website (/services/seo).\n\nLàm website WordPress bằng custom theme\n\nPerxel viết custom theme từ đầu cho từng website, không dùng theme mua sẵn trên ThemeForest hay các marketplace khác.\n\nGiao diện kéo thả linh hoạt\n\nGiao diện kéo thả giúp doanh nghiệp dễ dàng tái sử dụng các block thiết kế sẵn để dựng trang mới mà không cần can thiệp code. Perxel tối giản khu vực nhập liệu, tối ưu hóa khả năng biên tập trực quan và loại bỏ các cấu hình phức tạp.\n\nTối ưu hiệu năng thực tế\n\nLập trình custom theme loại bỏ mã nguồn dư thừa từ giao diện dựng sẵn, giúp website tải nhanh trên thiết bị di động. Ví dụ, website Khatra Tile (/works/khatra) do Perxel làm đạt Core Web Vitals trên dữ liệu người dùng thật, cả bản mobile.\n\nKiểm soát toàn bộ codebase\n\nPerxel kiểm soát chặt chẽ toàn bộ codebase và không dùng plugin lậu. Kết hợp cùng hệ thống ghi nhận nhật ký hoạt động của tài khoản quản trị, doanh nghiệp luôn nắm rõ mọi thao tác trên hệ thống.\n\nGiao diện quản trị dễ sử dụng\n\nPerxel dùng NectarBlocks, công cụ kéo thả xây dựng trên nền Gutenberg, để tạo khu vực soạn thảo trang cho khách hàng. Sau khi bàn giao, team vận hành có thể tự thêm trang mới, sắp xếp lại bố cục hoặc cập nhật nội dung ngay trên giao diện trực quan, không cần gọi lập trình viên mỗi khi có thay đổi nhỏ.\n\nDù dùng công cụ kéo thả để tạo trang, mọi chi tiết thiết kế theo bản vẽ Figma vẫn được Perxel lập trình riêng bằng code, không dùng các mẫu dựng sẵn. Giao diện vì vậy vừa dễ quản trị hàng ngày, vừa giữ đúng bản sắc thiết kế riêng của thương hiệu.\n\nWebsite bán hàng với WooCommerce\n\nNgoài website giới thiệu doanh nghiệp, Perxel lập trình custom theme cho cửa hàng trực tuyến trên nền WooCommerce, plugin thương mại điện tử tiêu chuẩn của hệ sinh thái WordPress. Trang danh mục, trang chi tiết sản phẩm, giỏ hàng và thanh toán đều được lập trình riêng theo đúng bản vẽ Figma, không dùng giao diện mặc định của WooCommerce.\n\nDoanh nghiệp tự quản lý sản phẩm, tồn kho, khuyến mãi và đơn hàng ngay trong khu vực quản trị, không phát sinh phí subscription tính theo doanh thu như các nền tảng SaaS thương mại điện tử.\n\nAn toàn và bảo mật\n\nĐịnh kiến cho rằng WordPress dễ bị tấn công là một góc nhìn chưa đầy đủ. Mã nguồn của WordPress được cập nhật các bản vá bảo mật thường xuyên và nhanh chóng. Rủi ro thực tế hầu hết phát sinh từ việc cài đặt quá nhiều plugin miễn phí không rõ nguồn gốc, dùng plugin lậu hoặc cấu hình hệ thống lỏng lẻo.\n\nPerxel xử lý bài toán này bằng hai nguyên tắc rõ ràng:\n\nNói không với plugin không rõ nguồn gốc\n\nPerxel chỉ dùng các công cụ premium có bản quyền chính thức, được chọn lọc và kiểm chứng qua nhiều dự án thực tế: Gravity Forms cho biểu mẫu, WPML cho đa ngôn ngữ, và NectarBlocks cho layout dạng block trên nền Gutenberg.\n\nThiết lập bảo mật từ kinh nghiệm vận hành\n\n- Kiểm soát và truy vết. Tích hợp hệ thống ghi nhận nhật ký hoạt động. Mọi thao tác cài đặt, chỉnh sửa nội dung hoặc lịch sử đăng nhập của tài khoản admin đều được lưu trữ rõ ràng, giúp quản trị viên truy vết khi phát sinh vấn đề.\n- Ngăn chặn xâm nhập. Thay đổi đường dẫn trang đăng nhập mặc định sang địa chỉ riêng, tự động chặn các IP dò quét mật khẩu (brute-force protection), và thiết lập tường lửa hạn chế spam biểu mẫu.\n\nBàn giao nhanh gọn, đầy đủ\n\nĐể loại bỏ sự bất tiện của các tài liệu hướng dẫn dạng PDF dài dòng và dễ thất lạc, Perxel bàn giao theo cách trực quan hơn:\n\n- Website Guide tích hợp trong admin. Perxel xây dựng một trang hướng dẫn sử dụng nằm ngay trong dashboard quản trị. Admin có thể truy cập bất kỳ lúc nào để xem hình ảnh mô tả, video hướng dẫn thao tác thực tế và các nút truy cập nhanh đến từng tính năng quản trị, không cần mở file tài liệu phức tạp.\n- Bàn giao 100% quyền sở hữu. Khi dự án kết thúc, toàn bộ thông tin tài khoản hosting, domain cùng các tài khoản dịch vụ bên thứ ba đều được bàn giao đầy đủ cho khách hàng. Website của bạn hoàn toàn độc lập, không bị ràng buộc kỹ thuật hay phụ thuộc vào Perxel, và có thể chuyển giao cho bộ phận kỹ thuật nội bộ hoặc bất kỳ đối tác nào khác bất cứ lúc nào.\n\nĐồng hành cùng creative agency và designer\n\nPerxel hoạt động như một đối tác kỹ thuật, không phải một đơn vị gia công thụ động. Chúng tôi chia sẻ chung tư duy thẩm mỹ và ngôn ngữ thiết kế với các designer.\n\nPerxel không đưa ra các cam kết phi kỹ thuật như \"giống 100% bản vẽ tĩnh\". Thay vào đó, chúng tôi chủ động thảo luận và phản biện kỹ thuật cần thiết cùng designer ngay từ bước phác thảo Figma để xử lý các responsive edge case và tìm phương án responsive tự nhiên nhất. Quy trình làm việc chuyên sâu cùng Perxel cũng giúp designer tích lũy thêm các insight kỹ thuật thực tế để hoàn thiện design system cho các sản phẩm tiếp theo.\n\nTối ưu chi phí đầu tư lâu dài\n\n- Không tốn phí subscription nền tảng định kỳ. Doanh nghiệp làm chủ hệ thống, không bị phát sinh chi phí tính theo số lượng trang, số lượng ngôn ngữ hay số lượng tài khoản biên tập như các công cụ no-code.\n- Vận hành nhẹ trên hosting tiêu chuẩn. Nhờ codebase custom gọn nhẹ, website chạy mượt trên mọi gói hosting tiêu chuẩn mà không đòi hỏi cấu hình phức tạp.\n\nFAQ\n\nChi phí làm website WordPress tùy vào số trang, số block cần lập trình và các tính năng như đa ngôn ngữ hay WooCommerce. Perxel báo giá sau khi xem bản Figma và thống nhất phạm vi công việc. Mức giá khởi điểm có ở trang Chi phí (/pricing).\n\nCác theme dựng sẵn thương mại được thiết kế cho hàng vạn người dùng khác nhau nên chứa nhiều code dư thừa để đáp ứng mọi tính năng có thể. Điều này khiến website cồng kềnh, tải chậm và khó tùy biến sâu. Lập trình custom theme tại Perxel là quá trình viết code riêng dựa trên đúng nhu cầu thực tế và thiết kế Figma của bạn. Giao diện của bạn sẽ độc bản, nhẹ, vận hành mượt và dễ nâng cấp về sau.\n\nĐược. Nhờ page builder NectarBlocks trên nền Gutenberg, nhân sự quản trị có thể dùng các block được Perxel lập trình sẵn để tự tạo trang mới như landing page chiến dịch hay bài viết. Do các quy chuẩn về responsive, khoảng cách và font chữ đã được cố định trong codebase, việc tự tạo trang diễn ra mượt mà và chuẩn mực mà không cần thuê lập trình viên chỉnh lại.\n\nPerxel thiết lập bảo mật ngay khi lập trình codebase, dựa trên kinh nghiệm vận hành thực tế. Hệ thống ghi nhận nhật ký đăng nhập và thao tác của admin giúp bạn kiểm soát toàn bộ hệ thống. Đường dẫn đăng nhập mặc định được thay đổi, brute-force protection được kích hoạt để tự động khóa các IP dò mật khẩu, và tường lửa được cấu hình để ngăn spam. Perxel cam kết không dùng plugin lậu.\n\nPerxel cung cấp license cho các plugin premium cốt lõi trong gói phát triển ban đầu, gồm Gravity Forms, WPML và NectarBlocks. Sau khi bàn giao, doanh nghiệp chỉ cần thanh toán phí duy trì domain và hosting định kỳ cho nhà cung cấp dịch vụ của mình, không phải trả thêm phí subscription ẩn nào từ Perxel.\n\nCó. Ngoài website giới thiệu doanh nghiệp, Perxel lập trình custom theme cho cửa hàng trực tuyến trên nền WooCommerce, gồm trang danh mục, trang sản phẩm, giỏ hàng và thanh toán. Giao diện được lập trình riêng theo bản vẽ Figma, không dùng theme WooCommerce mặc định.\n\nĐược. Nhờ codebase được tổ chức khoa học và tuân thủ các best practice mới nhất của WordPress, website của bạn tương thích tốt với các công nghệ tương lai. Perxel có thể lập trình thêm tính năng chuyên biệt hoặc viết thêm custom plugin để tích hợp vào hệ thống hiện tại bất cứ lúc nào mà không cần đập đi xây lại toàn bộ website.\n\nSau khi hoàn tất kiểm thử đa thiết bị và đa trình duyệt, Perxel bàn giao trực tiếp kèm trang Website Guide nằm trong admin. Toàn bộ mã nguồn và tài khoản sở hữu được chuyển giao 100%. Bạn không phụ thuộc vào Perxel và có thể bàn giao thẳng cho team kỹ thuật nội bộ. Perxel cũng hỗ trợ bảo trì kỹ thuật cho website hoạt động ổn định trong suốt thời hạn thỏa thuận của dự án.\n\nMuốn hiểu sâu hơn về NectarBlocks, xem Meet Nectarblocks (/insights/nectarblocks). Về danh sách plugin và chi phí bản quyền, xem Danh sách plugin WordPress (/insights/wordpress-plugin-list).\n\n1. W3Techs: Usage statistics of WordPress\n2. NectarBlocks\n3. Gravity Forms\n4. WPML"},{"kind":"service","locale":"vi","slug":"wordpress-plugins","title":"Lập trình plugin WordPress","shortTitle":"Plugin WordPress","excerpt":"Boutique studio lập trình và phát triển plugin WordPress theo tiêu chuẩn chính thống. Giải quyết bài toán vận hành, đồng bộ dữ liệu API và tự động hóa hệ thống.","categories":["WordPress"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/services/wordpress-plugins","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Một website hoạt động hiệu quả cần giải phóng sức vận hành thủ công cho doanh nghiệp. Khi hệ thống phình to, việc chắp vá mã nguồn bằng cách cài đặt hàng chục plugin từ bên thứ ba thường gây ra xung đột kỹ thuật, làm chậm tốc độ tải trang thực tế và tăng rủi ro bảo mật.\n\nDịch vụ lập trình custom plugin của Perxel giúp tinh gọn hệ thống bằng cách viết mã nguồn riêng, xử lý chính xác từng yêu cầu nghiệp vụ cụ thể. Chúng tôi tập trung vào việc tự động hóa các quy trình lặp đi lặp lại để tối ưu nguồn lực nhân sự và chi phí vận hành hàng ngày.\n\nCác ưu thế thực tế khi phát triển plugin tại Perxel\n\nĐồng bộ trải nghiệm quản trị\n\nPerxel dùng bộ giao diện wp-plugin-ui cho mọi sản phẩm của mình. Đây là bộ UI kit dùng chung giúp đảm bảo tính nhất quán về hiển thị, để trải nghiệm quản trị trong trang admin luôn thân thiện, trực quan và đồng bộ với phong cách thiết kế của WordPress.\n\nChuẩn mực tương thích hệ thống\n\nMọi plugin do Perxel xây dựng đều tuân thủ WordPress Coding Standards và Plugin Developer Handbook. Điều này đảm bảo tính tương thích lâu dài khi nâng cấp hệ thống lõi và hạn chế tối đa các lỗi xung đột kỹ thuật.\n\nĐánh giá trước khi tích hợp\n\nCác custom plugin của Perxel được tối ưu để hoạt động tốt nhất trên website dùng custom theme do Perxel phát triển. Với các website đang vận hành trên giao diện khác, Perxel sẵn sàng kiểm tra và đánh giá cấu trúc hệ thống để đưa ra phương án tích hợp an toàn và hiệu quả.\n\nMinh chứng qua các giải pháp đã triển khai\n\n- Plugin công khai cho cộng đồng. Perxel phát triển và chia sẻ plugin ACF IcoMoon trên thư viện chính thức của WordPress, giúp lập trình viên tích hợp và quản lý các trường icon tùy biến thông qua Advanced Custom Fields.\n- Tự động hóa dịch thuật bằng AI. Plugin mã nguồn mở trên GitHub kết nối trực tiếp với API của AI để tự động hóa quy trình dịch thuật nội dung đa ngôn ngữ. Trong một dự án cần dịch hơn 800 sản phẩm, Perxel triển khai giải pháp dịch qua API với tổng chi phí dưới 200.000 đồng và hoàn tất toàn bộ dữ liệu chỉ trong 2 tuần.\n- Tối ưu hình ảnh tự động. Plugin chuyên dụng tự động nén và tối ưu dung lượng hình ảnh ngay khi tải lên hệ thống quản trị, giúp website duy trì tốc độ tải nhanh mà không cần dịch vụ nén ảnh tính phí định kỳ của bên thứ ba.\n\nFAQ\n\nCác plugin có sẵn thường được viết để đáp ứng nhu cầu chung của hàng vạn người dùng nên chứa nhiều tính năng dư thừa làm chậm website hoặc dễ gây xung đột hệ thống. Custom plugin tại Perxel được lập trình tinh gọn từ gốc để giải quyết chính xác một hoặc một nhóm nhu cầu cụ thể của bạn, giúp tối giản mã nguồn, tối ưu hiệu năng và an toàn hơn.\n\nKhông ảnh hưởng. Nhờ tuân thủ các quy chuẩn lập trình chính thức và dùng các API tiêu chuẩn do WordPress cung cấp, plugin của Perxel có tính tương thích cao và hoạt động ổn định qua các đợt cập nhật của hệ thống lõi.\n\nCó. Perxel có thể lập trình custom plugin chuyên dụng để kết nối website với các hệ thống nội bộ như CRM, ERP, cổng thanh toán hoặc các dịch vụ API của bên thứ ba, giúp quy trình xử lý dữ liệu diễn ra tự động và trơn tru.\n\nLiên hệ với Perxel\n\n1. wp-plugin-ui\n2. WordPress Coding Standards\n3. Plugin Developer Handbook\n4. ACF IcoMoon"},{"kind":"service","locale":"vi","slug":"web-animation","title":"Web animation","shortTitle":null,"excerpt":"Boutique tech studio đưa các bản thiết kế tĩnh lên trình duyệt bằng chuyển động và micro-interactions tự nhiên, tối ưu hiệu năng tải trang từ kinh nghiệm làm việc thực tế.","categories":["Animation"],"tech":[{"id":"gsap","label":"GSAP"},{"id":"motion","label":"Motion"},{"id":"lottie","label":"Lottie"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/services/web-animation","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Mỗi dự án website tại Perxel là một bài toán vận hành riêng biệt. Có những khách hàng tìm kiếm khả năng kể chuyện thương hiệu như Tam Coc Garden hay Sun DMD. Có những đối tác đặt tính ổn định, chỉn chu và chuẩn mực lên hàng đầu như REE, Cảng Quốc tế Long An hay RMIT. Và cũng có những dự án mong muốn cả hai yếu tố trên như Huynchi hay Tuan Loc Commodities.\n\nVới kinh nghiệm nhiều năm phục vụ khách hàng đa dạng về cả ngành nghề lẫn quốc gia tại các agency lớn, Perxel dung hòa các nhu cầu này bằng trải nghiệm thực tế trên môi trường web. Sự dung hòa đó thể hiện qua các phản biện kỹ thuật cần thiết khi làm việc cùng designer ngay từ những bước đầu tiên. Chúng tôi đưa các bản vẽ tĩnh lên trình duyệt bằng chuyển động và micro-interactions tinh tế, giúp website có chiều sâu nhưng vẫn giữ trọn hiệu năng vận hành.\n\nBa giá trị cốt lõi\n\nDung hòa tính nghệ thuật\n\nPerxel thấu hiểu nhu cầu thực tế của từng thương hiệu. Chúng tôi dung hòa giữa câu chuyện thương hiệu và sự ổn định, chỉn chu của doanh nghiệp lớn, mang đến trải nghiệm tương tác phù hợp với bối cảnh.\n\nPhản biện kỹ thuật cần thiết\n\nPerxel làm việc sát sao cùng designer từ bước phác thảo Figma. Chúng tôi chủ động góp ý về tính khả thi của chuyển động, xử lý các khoảng trống thiết kế và đề xuất phương án responsive.\n\nLựa chọn công nghệ linh hoạt\n\nKhông phụ thuộc một công cụ, Perxel kết hợp linh hoạt giữa GSAP, CSS, JavaScript thuần và các thư viện tinh gọn. Chúng tôi thậm chí tự viết mã nguồn riêng cho từng dự án để website tải nhanh nhất có thể.\n\nCông cụ linh hoạt và tối ưu codebase\n\nCác chuyển động 2D phức tạp được lập trình bằng GSAP để kiểm soát timeline chính xác. Tuy nhiên, thay vì lạm dụng một công cụ duy nhất, lợi thế của Perxel là khả năng vận dụng linh hoạt nhiều giải pháp khác nhau tùy yêu cầu dự án.\n\nVới các chuyển động cơ bản, Perxel ưu tiên CSS animation hoặc JavaScript thuần để giữ website nhẹ nhất có thể. Trong nhiều trường hợp, các thư viện siêu tinh gọn như motion được lựa chọn để tối ưu hiệu năng tải trang.\n\nVới các dự án đặc thù yêu cầu tối ưu tối đa hiệu năng và không chứa mã nguồn dư thừa, Perxel tự phát triển các thư viện animation riêng như cuajs (tối ưu chuyển động) và scroll-snooper (tối ưu tương tác cuộn trang), đã được chia sẻ công khai trên GitHub.\n\nVới ảnh minh hoạ chuyển động như icon hay illustration, Perxel dùng Lottie vì file nhẹ, sắc nét và đổi được màu theo brand. Xem thêm bài Lottie là gì và cách dùng cho website (/insights/lottie-animation).\n\nĐảm bảo tương thích bằng kinh nghiệm thực tế\n\nKiểm thử trên các thiết bị di động thực tế luôn là một quy chuẩn kiểm soát chất lượng quan trọng trong ngành để đảm bảo sự đồng bộ hiển thị. Với kinh nghiệm qua hàng trăm dự án đa dạng, Perxel biết chính xác hiệu ứng nào nên đi kèm kỹ thuật nào để website hiển thị ổn định trên đa số trình duyệt và thiết bị của người dùng cuối.\n\nChúng tôi luôn thiết lập responsive animation một cách thông minh, tự động điều chỉnh hoặc tinh giản hiệu ứng khi phát hiện thiết bị có cấu hình hạn chế, tránh hiện tượng giật lag hoặc gây nóng máy, mang lại trải nghiệm cuộn trang tự nhiên.\n\nFAQ\n\nChuyển động chỉ gây chậm khi lạm dụng code cẩu thả hoặc nhồi nhét thư viện nặng. Với tư duy tối giản và khả năng tự viết mã nguồn riêng như scroll-snooper hay cuajs, Perxel luôn tính toán để website đạt hiệu suất tối ưu, mượt nhưng vẫn tải nhanh thực tế.\n\nNhờ kinh nghiệm kiểm soát responsive animation, Perxel biết cách tinh giản hoặc điều chỉnh hiệu ứng cho phù hợp với thao tác vuốt chạm trên thiết bị di động, đảm bảo tính đồng bộ và ổn định lâu dài.\n\nĐược. Là một đối tác kỹ thuật am hiểu về chuyển động từ năm 2016, Perxel dựa trên cá tính thương hiệu của bạn để chủ động đề xuất nhịp điệu chuyển động phù hợp, sau đó thảo luận cùng designer để hiện thực hóa sản phẩm.\n\nKhông ảnh hưởng. Codebase custom của Perxel tách biệt hoàn toàn giữa dữ liệu nội dung và logic chuyển động. Bạn có thể tự do thay đổi văn bản, hình ảnh trong trang quản trị mà không làm ảnh hưởng đến các hiệu ứng đã lập trình trước đó.\n\nLiên hệ với Perxel\n\n1. GSAP\n2. Motion\n3. Perxel trên GitHub"},{"kind":"service","locale":"vi","slug":"nextjs","title":"Website Next.js & Headless CMS","shortTitle":"Next.js & Headless CMS","excerpt":"Boutique tech studio lập trình website trên nền tảng Next.js kết hợp Headless CMS (TinaCMS, Prismic). Tối ưu hiệu năng tải trang tại hạ tầng Edge, biên tập trực quan và kiểm soát trọn vẹn chi phí vận hành.","categories":["Next.js"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"prismic","label":"Prismic"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/services/nextjs","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Với các chiến dịch marketing, landing page giới thiệu sản phẩm hay website doanh nghiệp hiện đại, điều quan trọng nhất là tốc độ bàn giao, hiệu năng tải trang tức thì và chi phí duy trì tối giản. Không cần đến những hệ quản trị cồng kềnh hay máy chủ phức tạp, Next.js kết hợp Headless CMS mang lại sự cân bằng lý tưởng: frontend React chuẩn mực, giao diện biên tập trực quan cho team marketing và khả năng vận hành mượt mà tại hạ tầng Edge mà không phát sinh chi phí duy trì hàng tháng.\n\nLợi thế kỹ thuật của Next.js\n\nNext.js kết hợp sức mạnh của React hiện đại với khả năng render linh hoạt (Server-Side Rendering và Static Generation). Toàn bộ frontend, logic xử lý metadata chuẩn SEO, tối ưu hình ảnh và các API endpoint trung gian đều quy tụ trong một codebase duy nhất theo cấu trúc rõ ràng.\n\n- Tải trang tức thì tại Edge. Tận dụng hạ tầng CDN toàn cầu (Cloudflare Workers qua OpenNext), website phản hồi người dùng gần như ngay lập tức với TTFB dưới 50ms, không phụ thuộc vào web server truyền thống.\n- Tách bạch frontend và quản trị nội dung. Developer tự do tạo dựng trải nghiệm visual hay micro-interactions bám sát Figma mà không bị gò bó bởi khuôn mẫu của các CMS truyền thống.\n- Sẵn sàng mở rộng thành Web App. Khi doanh nghiệp cần phát triển thêm dashboard, tích hợp cổng thanh toán hoặc kết nối API nội bộ, codebase Next.js sẵn sàng đáp ứng mà không phải tái cấu trúc toàn bộ hệ thống.\n\nHai lựa chọn Headless CMS\n\nMỗi doanh nghiệp có quy mô nội dung và quy trình vận hành khác nhau. Perxel tập trung làm chủ hai giải pháp Headless CMS phù hợp và ổn định nhất với Next.js hiện nay:\n\nPrismic\n\nPrismic (/insights/prismic-headless-cms) là Headless CMS thương mại với giao diện quản trị hiện đại, thiết kế theo mô hình Page Builder dựa trên Slices, giúp team Marketing tự sắp xếp bố cục nội dung mà không làm vỡ layout thiết kế gốc.\n\nGói miễn phí hỗ trợ 1 tài khoản editor, 2 ngôn ngữ và 100GB băng thông mỗi tháng. Khi cần mở rộng, gói Starter khoảng $10/tháng nâng lên 3 tài khoản editor và 3 ngôn ngữ, đáp ứng tốt phần lớn website giới thiệu doanh nghiệp và landing page tiêu chuẩn.\n\nTinaCMS\n\nTinaCMS (/insights/tinacms) là Headless CMS mã nguồn mở, vận hành theo mô hình Git-backed: nội dung được lưu trực tiếp trong repository của dự án thay vì một cơ sở dữ liệu riêng. Nhờ vậy website không giới hạn số lượng ngôn ngữ và không tính phí theo băng thông truy cập. Điểm đặc trưng của TinaCMS là trải nghiệm Click-to-Edit trực tiếp trên giao diện.\n\nGói miễn phí hỗ trợ 2 tài khoản editor và không giới hạn ngôn ngữ. Khi team biên tập lớn hơn, gói Team khoảng $24/tháng nâng lên 3 tài khoản editor. Với đa số website vận hành bởi 1 đến 2 người phụ trách nội dung, gói miễn phí đã đáp ứng đầy đủ.\n\nLựa chọn phù hợp theo nhu cầu vận hành\n\nDựa trên kinh nghiệm triển khai thực tế, Perxel gợi ý hướng tiếp cận theo bài toán cụ thể:\n\n- Chọn Prismic khi cần hệ CMS đầy đủ tính năng. Phù hợp với hầu hết website doanh nghiệp và landing page cần content modeling linh hoạt, workflow xuất bản rõ ràng hoặc vận hành dưới 3 ngôn ngữ.\n- Chọn TinaCMS khi ưu tiên chi phí và trải nghiệm Click-to-Edit. Phù hợp khi website cần từ 3 ngôn ngữ trở lên hoặc có lượng truy cập lớn mà không muốn phát sinh chi phí theo băng thông CDN.\n\nTìm hiểu chi tiết sự khác biệt kỹ thuật tại bài phân tích So sánh TinaCMS và Prismic (/insights/tinacms-vs-prismic).\n\nDự án thực tế đã kiểm chứng\n\nNăng lực triển khai Next.js kết hợp Headless CMS của Perxel được đúc kết qua các sản phẩm và case study thực tế:\n\n- Atlas Robotics (TinaCMS). Bộ khung marketing website B2B đa ngôn ngữ (Anh, Việt, Trung), xử lý dữ liệu media dung lượng lớn và vận hành mượt mà trên Cloudflare Workers với chi phí máy chủ $0/tháng. Xem thêm tại Atlas Robotics (/products/atlas-robotics).\n- Foldables (Prismic). Content modeling qua Prismic CLI, thiết lập Slice Machine và tự động revalidate nội dung tức thì qua webhook trên Cloudflare Workers. Xem thêm tại Foldables (/products/foldables).\n- Growtrics (TinaCMS). Marketing website cho EdTech startup tại Singapore, tích hợp TinaCMS và bàn giao hoàn chỉnh trong 3 ngày làm việc. Xem thêm tại Growtrics (/works/growtrics).\n- Chứng nhận chính thức: Kỹ sư chính tại Perxel đạt chứng nhận TinaCMS Certified Developer (/insights/certified-tinacms-developer) từ chính team phát triển TinaCMS.\n\nSo sánh Next.js và WordPress\n\nCả hai nền tảng đều phục vụ tốt cho mục đích marketing website. Khoảng cách chi phí giữa hai lựa chọn trên thực tế không quá lớn, nhưng mỗi nền tảng có thế mạnh riêng về mặt kiến trúc:\n\n- Lợi thế hạ tầng của Next.js: Khả năng triển khai tĩnh trên Cloudflare Workers với gói miễn phí, giúp giảm thiểu chi phí hosting cho website quy mô vừa và nhỏ.\n- Khả năng mở rộng: Next.js xây dựng trên React nên linh hoạt hơn khi cần phát triển sâu về sau (như tích hợp API riêng, kết nối CRM hoặc hệ thống nghiệp vụ đặc thù).\n- Khi nào nên chọn: Chọn Next.js nếu bạn định hướng phát triển website theo hướng web app hoặc cần tích hợp sâu với các dịch vụ bên thứ ba. Chọn WordPress khi website thuần túy phục vụ nội dung thông tin; giải pháp làm website WordPress bằng custom theme (/services/wordpress-custom-theme) của Perxel mang lại trải nghiệm biên tập trực quan và hiệu năng tương đương.\n\nĐồng hành kỹ thuật cùng agency và doanh nghiệp\n\nPerxel hoạt động như một đối tác kỹ thuật am hiểu thẩm mỹ, không phải đơn vị gia công mã nguồn thụ động.\n\nBảo toàn ý đồ thiết kế từ Figma\n\nMọi khối giao diện được chuyển đổi thành React component chuẩn mực, giữ đúng tỷ lệ lưới, nhịp điệu typography và chuyển giao mượt mà từ Figma sang website production (/insights/figma-handoff), hiển thị ổn định trên đa thiết bị và đa trình duyệt (/insights/cross-browser-cross-device).\n\nLàm chủ 100% mã nguồn và hạ tầng\n\nToàn bộ mã nguồn trên Git repository, tài khoản hosting Cloudflare, domain và các tài khoản dịch vụ liên quan đều được bàn giao đầy đủ. Website hoàn toàn độc lập và không bị ràng buộc kỹ thuật hay phụ thuộc vào Perxel.\n\nTối ưu hóa chi phí vận hành lâu dài\n\nNhờ kiến trúc static và edge rendering, website không đòi hỏi máy chủ cấu hình cao hay cơ sở dữ liệu tốn kém. Doanh nghiệp tiết kiệm ngân sách hosting hàng tháng mà vẫn duy trì tốc độ tải trang cao cấp.\n\nFAQ\n\nHoàn toàn được. Cả Prismic và TinaCMS đều cung cấp giao diện quản lý trực quan dạng live preview hoặc kéo thả block. Nhân sự phụ trách nội dung có thể tự do cập nhật văn bản, thay đổi hình ảnh và sắp xếp các khối trên trang mà không cần can thiệp vào code.\n\nCó. Website Next.js tĩnh kết hợp Headless CMS không có hệ thống plugin phức tạp hay lỗ hổng cơ sở dữ liệu cần vá lỗi thường xuyên như các CMS truyền thống. Sau khi bàn giao, bạn có thể tiếp tục quản lý nội dung độc lập. Developer chỉ cần tham gia khi bạn muốn bổ sung tính năng, thêm block mới hoặc thay đổi cấu trúc thiết kế.\n\nKhông. Cả Prismic lẫn TinaCMS đều không giới hạn số lượng trang hoặc bài viết theo biểu phí lưu trữ. Điều này rất thuận tiện cho các chiến dịch marketing thường xuyên phát sinh landing page mới.\n\nCó. Hệ thống có thể thiết lập đa ngôn ngữ hoàn chỉnh từ cấu trúc URL, nội dung trong CMS đến giao diện hiển thị. Gói miễn phí của TinaCMS hỗ trợ không giới hạn ngôn ngữ, trong khi gói miễn phí của Prismic hỗ trợ tối đa 2 ngôn ngữ.\n\nPerformance và SEO là lợi thế cốt lõi của stack này. Nhờ khả năng pre-render HTML tĩnh và phân phối qua mạng lưới Edge CDN của Cloudflare, website đạt tốc độ phản hồi tức thì với TTFB dưới 50ms. Đồng thời, Next.js cho phép kiểm soát toàn diện các thẻ meta, Open Graph và dữ liệu có cấu trúc cho từng trang. Các website Next.js Perxel lập trình như Foldables và Atlas Robotics đều đạt 100 điểm SEO trên PageSpeed. Xem thêm tại SEO và GEO cho website (/services/seo).\n\nWebflow và Framer có chi phí ban đầu thấp hơn khi tự dựng bằng công cụ no-code. Tuy nhiên, khi website tăng trưởng về lượng truy cập, số lượng trang hoặc ngôn ngữ, phí subscription hàng tháng của các nền tảng no-code sẽ tăng nhanh. Next.js + Headless CMS đòi hỏi chi phí phát triển ban đầu từ lập trình viên, nhưng đổi lại bạn sở hữu trọn vẹn mã nguồn và giữ chi phí vận hành hàng tháng ở mức tối giản.\n\nCó. Perxel đồng hành phía sau các creative agency và designer, đảm nhận từ khâu lập trình frontend, tích hợp CMS đến triển khai hạ tầng. Agency tiếp tục làm việc trực tiếp với khách hàng của mình. Xem thêm chi tiết tại Đối tác phát triển website (/services/development-partner).\n\nĐược. Kiến trúc component của React và Next.js tương thích tự nhiên với các workflow dựa trên Design System. Perxel có thể tuân thủ chính xác token thiết kế, coding standard và component library sẵn có của từng agency.\n\nĐọc thêm\n\n- TinaCMS & Next.js (/insights/tinacms)\n- Prismic & Next.js (/insights/prismic-headless-cms)\n- So sánh TinaCMS và Prismic (/insights/tinacms-vs-prismic)\n\nYêu cầu Demo\n\n1. Next.js\n2. TinaCMS\n3. TinaCMS: Pricing\n4. Prismic\n5. Prismic: Pricing\n6. Cloudflare Workers: Pricing"},{"kind":"service","locale":"vi","slug":"development-partner","title":"Đối tác phát triển website","shortTitle":"Đối tác phát triển","excerpt":"Boutique tech studio đồng hành cùng creative agency và designer tự do, lập trình website từ thiết kế Figma, chủ động phản biện kỹ thuật và hỗ trợ chính sách white label chuyên nghiệp.","categories":["Tư vấn kỹ thuật"],"tech":[{"id":"figma","label":"Figma"},{"id":"github","label":"GitHub"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/services/development-partner","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Một bản thiết kế xuất sắc trên Figma chỉ thực sự trọn vẹn khi được đưa lên trình duyệt với đúng tỷ lệ hiển thị, nhịp điệu tương tác tự nhiên và hiệu năng vận hành ổn định. Sự kết nối chặt chẽ giữa tư duy thẩm mỹ của designer và năng lực lập trình của kỹ sư là chìa khóa tạo nên thành công của dự án.\n\nPerxel đồng hành sát sao cùng các creative agency và designer tự do như một cánh tay nối dài về kỹ thuật. Chúng tôi chia sẻ chung tư duy thẩm mỹ để thấu hiểu ngôn ngữ thiết kế của bạn, chủ động hỗ trợ giải quyết các bài toán lập trình phức tạp và giải phóng áp lực kỹ thuật để bạn tập trung vào thế mạnh sáng tạo cốt lõi.\n\nCác lợi thế thực tế khi đồng hành cùng Perxel\n\nTối ưu chi phí thiết kế di động\n\nPerxel đáp ứng chính xác mọi bản vẽ di động từ designer. Ngoài ra, khi agency muốn tối ưu chi phí thiết kế, chúng tôi sẵn sàng tự xử lý responsive tự nhiên dựa trên bản desktop mà vẫn đảm bảo website hiển thị tốt.\n\nBảo mật thông tin và white label\n\nPerxel cung cấp dịch vụ white label và cam kết bảo mật thông tin (NDA). Mọi mã nguồn và thông tin hiển thị khi bàn giao đến khách hàng cuối đều được gắn nhãn thương hiệu của chính agency, đảm bảo sự đồng bộ chuyên nghiệp.\n\nTương tác tự nhiên\n\nVới kinh nghiệm chuyên sâu về web animation và web interaction, Perxel đưa vào website các hiệu ứng tương tác tự nhiên và micro-interactions tinh tế, giúp bản thiết kế tĩnh sinh động hơn mà không ảnh hưởng đến tốc độ tải trang.\n\nQuy trình phối hợp\n\nPerxel tham gia thảo luận ngay từ khi nhận brief hoặc bản phác thảo đang hình thành, giải đáp các thắc mắc kỹ thuật, đánh giá tính khả thi, đề xuất phương án tiếp cận và làm rõ scope dự án.\n\nTriển khai viết mã nguồn sạch dựa trên các quy chuẩn lập trình chính thống, tích hợp các bộ UI kit tự phát triển để mang lại trải nghiệm sử dụng tốt cho người quản trị.\n\nTiếp nhận trực tiếp phản hồi từ cả phía agency lẫn khách hàng cuối của agency, thực hiện các tinh chỉnh cần thiết để website đạt chất lượng tối đa trước khi đưa vào vận hành.\n\nBàn giao mã nguồn hoàn chỉnh và hướng dẫn vận hành chi tiết để website hoạt động ổn định lâu dài.\n\nFAQ\n\nCó. Perxel sẵn sàng ký NDA để bảo mật thông tin dự án và cung cấp dịch vụ White Label. Toàn bộ mã nguồn, thông tin liên hệ và hiển thị trong trang quản trị đều được gắn nhãn thương hiệu của agency, đảm bảo tính nhất quán trước đối tác và khách hàng cuối.\n\nKhi agency muốn tối ưu chi phí thiết kế và phát triển màn hình di động, Perxel có thể tự phát triển giao diện di động bám sát ngôn ngữ thiết kế của bản desktop. Việc thiết kế và lập trình thêm nhiều màn hình riêng biệt sẽ làm tăng chi phí tương ứng, nên giải pháp này giúp tối ưu ngân sách cho agency. Với các trang đòi hỏi storytelling phức tạp hoặc bố cục quá đặc thù, Perxel khuyến nghị agency nên vẽ bản di động riêng.\n\nPerxel bàn giao toàn bộ mã nguồn sạch của dự án, đồng thời hỗ trợ agency thiết lập website lên môi trường vận hành thực tế và hướng dẫn quản trị chi tiết để website hoạt động ổn định trước khi bàn giao cho khách hàng cuối.\n\nLiên hệ với Perxel"},{"kind":"service","locale":"vi","slug":"ai-solutions","title":"Giải pháp AI & Tích hợp hệ thống","shortTitle":"Giải pháp AI","excerpt":"Boutique tech studio lập trình lớp API và giao thức MCP kết nối AI với dữ liệu doanh nghiệp, đồng hành quản trị API key, ngân sách và giám sát chất lượng theo tiêu chuẩn kỹ thuật.","categories":["AI"],"tech":[{"id":"chatgpt","label":"ChatGPT"},{"id":"claude","label":"Claude"},{"id":"gemini","label":"Gemini"},{"id":"openrouter","label":"OpenRouter"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/services/ai-solutions","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Ứng dụng AI (ChatGPT, Claude, Gemini) vào hệ thống vận hành doanh nghiệp không đơn thuần là gắn một cửa sổ chat có sẵn hoặc cài plugin tự động hóa đóng gói. Lạm dụng các công cụ đóng gói sẵn thường kéo theo rủi ro phụ thuộc hạ tầng bên thứ ba, rò rỉ dữ liệu nội bộ và chi phí API khó kiểm soát.\n\nKiến trúc vận hành là điểm khởi đầu\n\nPerxel tiếp cận giải pháp AI như một đối tác kỹ thuật đồng hành, tập trung vào năng lực lập trình lớp API chuyên biệt và ứng dụng giao thức MCP (Model Context Protocol). Dù xây dựng trên nền tảng sẵn có như WordPress hay phát triển ứng dụng Next.js độc lập, Perxel triển khai theo cơ chế dùng bao nhiêu trả bấy nhiêu, giúp doanh nghiệp kiểm soát ngân sách chặt chẽ và giữ trọn quyền làm chủ tài sản số.\n\nBa trụ cột trong giải pháp AI tại Perxel\n\n- Kiến trúc linh hoạt. Perxel tích hợp chatbot và AI trực tiếp trên dữ liệu sẵn có (WordPress, Next.js) khi cấu trúc đủ sạch. Khi cần thiết, chúng tôi xây dựng hệ thống độc lập và đồng bộ dữ liệu hai chiều để tối ưu vận hành.\n- Chi phí theo nhu cầu thực tế. Kết nối qua AI Gateway như OpenRouter hoặc gọi API trực tiếp, kết hợp công cụ đo lường như Langfuse để kiểm soát chất lượng câu trả lời và ngân sách minh bạch.\n- Làm chủ tài sản và quản trị. Doanh nghiệp đứng tên tài khoản API key. Perxel đồng hành cài đặt hạn mức ngân sách và bàn giao mã nguồn sạch, không thu phí bản quyền định kỳ.\n\nCác hạng mục phát triển\n\nLập trình API Layer và MCP Layer\n\nXây dựng lớp API trung gian và giao thức MCP (xem dịch vụ MCP server (/services/mcp-server)) giúp các mô hình AI truy vấn dữ liệu doanh nghiệp an toàn theo thời gian thực. Mô hình này đã vận hành thực tế qua dự án OpenWallet (/works/openwallet), cung cấp dữ liệu thẻ ngân hàng dạng cấu trúc cho AI Assistant Owie và các công cụ AI bên ngoài qua một MCP Server riêng.\n\nChatbot trên nền dữ liệu doanh nghiệp\n\nWordPress là nguồn dữ liệu điển hình để tích hợp chatbot trực tiếp khi cấu trúc đủ sạch. Với các hệ thống phức tạp hơn, Perxel xây dựng chatbot trên Next.js hoặc tách thành hệ thống độc lập, đồng bộ dữ liệu hai chiều để đảm bảo an toàn và hiệu suất.\n\nTự động hóa xử lý dữ liệu quy mô lớn\n\nỨng dụng AI để giải quyết các bài toán vận hành có khối lượng dữ liệu lớn. Trong dự án Khatra Tile (/works/khatra), Perxel xây dựng plugin Perxel AI Translate để dịch gần 1.000 bài viết và sản phẩm sang tiếng Anh, với chi phí API theo cơ chế dùng bao nhiêu trả bấy nhiêu thấp hơn đáng kể so với các dịch vụ trả phí cố định.\n\nQuản trị AI theo tiêu chuẩn kỹ thuật\n\nTự động lưu vết từng truy vấn qua công cụ Langfuse, đánh giá độ chính xác câu trả lời, phát hiện phản hồi chưa đạt chuẩn và liên tục tối ưu prompt.\n\nDoanh nghiệp đứng tên tài khoản API key. Perxel đồng hành cài đặt hạn mức chi tiêu (budget cap) và cảnh báo tự động để chi phí vận hành luôn nằm trong tầm kiểm soát.\n\nKết nối qua AI Gateway quen thuộc như OpenRouter hoặc làm việc trực tiếp với API của các nhà cung cấp mô hình (OpenAI, Anthropic, Google), tính phí theo lượng token tiêu thụ thực tế.\n\nPhù hợp khi nào?\n\n- Khi doanh nghiệp muốn kết nối chatbot hoặc AI trực tiếp trên dữ liệu vận hành sẵn có.\n- Khi cần một lớp API hoặc MCP chuẩn hóa để AI Assistant truy vấn dữ liệu an toàn.\n- Khi khối lượng nội dung cần xử lý (dịch thuật, tổng hợp) đủ lớn để việc tự động hóa bằng API tiết kiệm hơn dịch vụ trả phí cố định.\n- Khi ngân sách API cần được giám sát và kiểm soát chặt chẽ thay vì phó mặc cho nhà cung cấp đóng gói sẵn.\n\nFAQ\n\nCác dịch vụ đóng gói sẵn thường thu phí bản quyền cố định hàng tháng và lưu dữ liệu trên máy chủ bên thứ ba. Giải pháp của Perxel dựa trên cơ chế dùng bao nhiêu trả bấy nhiêu qua API, đi kèm hạn mức ngân sách để kiểm soát chi phí và mã nguồn riêng bàn giao cho doanh nghiệp.\n\nPerxel tích hợp chatbot trực tiếp trên dữ liệu sẵn có của WordPress hoặc Next.js khi cấu trúc dữ liệu đủ sạch. Khi cần tách biệt vận hành để đảm bảo an toàn và hiệu suất, Perxel xây dựng một hệ thống AI độc lập và thiết lập cơ chế đồng bộ dữ liệu tự động.\n\nPerxel triển khai giám sát AI Observability (như Langfuse) để lưu vết và đo lường chất lượng từng câu trả lời. Kết hợp với giao thức MCP chuẩn hóa dữ liệu đầu vào, hệ thống chỉ truy xuất đúng kho dữ liệu được phân quyền, hạn chế sai lệch thông tin.\n\nDoanh nghiệp đứng tên sở hữu tài khoản API key. Perxel đồng hành hỗ trợ quản lý: cài đặt hạn mức chi tiêu, theo dõi mức tiêu thụ token và đưa ra cảnh báo kịp thời để hệ thống vận hành ổn định.\n\nLiên hệ với Perxel\n\n1. OpenRouter\n2. Langfuse"},{"kind":"service","locale":"vi","slug":"seo","title":"SEO và GEO cho website","shortTitle":"SEO & GEO","excerpt":"Perxel xây cấu trúc trang theo từ khóa khách hàng thật sự tìm, để Google xếp hạng và các công cụ AI như ChatGPT, Gemini đọc đúng, trích dẫn đúng nội dung. Bàn giao website đạt 100 điểm SEO trên PageSpeed, trên website đang có hoặc website mới.","categories":["Tư vấn kỹ thuật"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"nextjs","label":"Next.js"},{"id":"pagespeed","label":"PageSpeed Insights"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/services/seo","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Trước khi một trang được xếp hạng, Google phải đọc được nó: biết trang nói về điều gì, thuộc nhóm nội dung nào và liên quan đến những trang nào khác. Các công cụ AI như ChatGPT, Gemini hay phần AI Overviews trên Google cũng đọc website theo cách tương tự trước khi trích dẫn. Phần này nằm trong code và cấu trúc trang, nên Perxel làm nó ngay trong quá trình lập trình, trên WordPress lẫn Next.js.\n\nNhững gì Perxel cam kết khi bàn giao\n\n100 điểm SEO trên PageSpeed khi bàn giao\n\nTrang chủ, trang dịch vụ, trang sản phẩm và bài viết đều được kiểm tra bằng Lighthouse trên cả mobile lẫn desktop trước khi bàn giao. Lần đo ngày 13/10/2026 bằng Lighthouse 12, các website perxel.com, Khatra Tile (/works/khatra), Sundmd, Foldables (/products/foldables) và Atlas Robotics (/products/atlas-robotics) đều đạt 100 điểm SEO trên cả mobile lẫn desktop.\n\nKết quả PageSpeed Insights bản mobile của năm website do Perxel lập trình, đo ngày 13/10/2026.\n\nHai yếu tố trong điểm này do người biên tập nội dung viết sau bàn giao là mô tả ảnh (alt text) và chữ trên đường dẫn. Vì vậy, trường alt text được đặt bắt buộc trong CMS để điểm số không bị giảm khi website có thêm bài mới.\n\nCấu trúc trang theo từ khóa khách hàng thật sự tìm\n\nPerxel lập sơ đồ trang trước khi lập trình: mỗi trang nhắm một cụm từ khóa chính, các trang liên quan dẫn link sang nhau theo thứ tự người đọc cần. Google hiểu được website gồm những chủ đề nào, còn người đọc đi từ trang này sang trang khác theo một mạch rõ ràng thay vì quay lại trang chủ.\n\nDữ liệu có cấu trúc cho Google và AI\n\nThông tin doanh nghiệp, địa chỉ, sản phẩm, bài viết và đường dẫn breadcrumb được khai báo bằng dữ liệu có cấu trúc (JSON-LD). Website nhiều ngôn ngữ có thẻ hreflang để Google hiển thị đúng phiên bản cho từng người đọc. Ngoài ra, file llms.txt tóm tắt website để các công cụ AI đọc nhanh nội dung chính.\n\nGEO: để các công cụ AI đọc và trích dẫn website\n\nGEO (Generative Engine Optimization) là phần việc giúp nội dung website được ChatGPT, Gemini, Perplexity hay AI Overviews trên Google đọc đúng và nhắc đến khi trả lời người dùng. Nền tảng vẫn là SEO kỹ thuật ở trên, Perxel làm thêm bốn việc:\n\n- Mở cửa cho bot AI. Perxel kiểm tra robots.txt, cấu hình Cloudflare và hosting để GPTBot, ClaudeBot hay PerplexityBot không bị chặn hoặc giới hạn mà doanh nghiệp không hay biết. Nhiều gói hosting và tường lửa có sẵn quy tắc chặn bot, nên bước này cần kiểm tra trên từng website.\n- Viết nội dung để AI trích được. Mỗi trang trả lời thẳng câu hỏi chính ngay ở đoạn đầu, có tiêu đề rõ ràng, phần câu hỏi thường gặp, số liệu kèm ngày và nguồn.\n- Nguồn dữ liệu cho máy đọc. Ngoài JSON-LD và llms.txt, website Next.js có thể có thêm một nguồn dữ liệu dạng JSON hoặc một MCP server. Website Perxel dùng chính nguồn dữ liệu này cho trợ lý Ask Perxel trả lời khách truy cập.\n- Đo lượt truy cập từ AI. Lượt truy cập đến từ chatgpt.com, perplexity.ai hay gemini.google.com được tách riêng trong Google Analytics, để doanh nghiệp biết GEO có mang lại khách hay không.\n\nLàm trên website đang có hay làm website mới\n\nNếu website hiện tại vẫn chỉnh sửa được, Perxel ưu tiên giữ lại. Với Khatra Tile (/works/khatra), một website WordPress hơn 10 năm tuổi với gần 800 sản phẩm, Perxel viết lại toàn bộ theme nhưng giữ nguyên cấu trúc đường dẫn, nên thứ hạng của các từ khóa quan trọng trong ngành gạch vẫn ổn định sau khi ra mắt giao diện mới.\n\n- Website WordPress. Perxel cấu hình Rank Math hoặc Yoast SEO và sửa phần theme mà plugin không với tới được. Khatra Tile dùng Rank Math để khai báo địa chỉ và tọa độ của doanh nghiệp, kèm hai phiên bản tiếng Việt và tiếng Anh. Sundmd dùng Yoast SEO để tạo breadcrumb và file llms.txt tự động.\n- Website Next.js. Metadata, sitemap, dữ liệu có cấu trúc và llms.txt được viết trực tiếp trong code nên luôn khớp với nội dung trong CMS. Website Perxel còn có thêm một nguồn dữ liệu dạng JSON và một MCP server để các công cụ AI đọc nội dung đầy đủ, không cần đoán từ giao diện.\n\nCác bước triển khai\n\n1. Kiểm tra website hiện tại. Đo điểm SEO, kiểm tra sitemap, đường dẫn canonical, dữ liệu có cấu trúc, các trang Google đang lập chỉ mục trong Search Console và việc bot AI có truy cập được website hay không.\n2. Lập sơ đồ trang và từ khóa. Mỗi trang có một cụm từ khóa chính, một mục đích rõ ràng và danh sách các trang nó dẫn link đến. Bạn duyệt sơ đồ này trước khi Perxel bắt tay vào code.\n3. Triển khai. Chỉnh cấu trúc trang, metadata, dữ liệu có cấu trúc và link nội bộ trên website đang có, hoặc xây mới theo sơ đồ đã duyệt.\n4. Kiểm tra và bàn giao. Chạy Lighthouse trên từng loại trang, gửi sitemap lên Google Search Console và hướng dẫn team nội dung giữ các chỉ số này khi đăng bài mới.\n\nMỗi website có quy mô và hiện trạng khác nhau, nên Perxel gửi báo giá sau bước kiểm tra đầu tiên.\n\nPhạm vi dịch vụ\n\nPerxel làm phần nền kỹ thuật và cấu trúc của website. Viết nội dung định kỳ và xây dựng backlink không nằm trong dịch vụ này. Thứ hạng trên Google và việc được các công cụ AI trích dẫn còn phụ thuộc vào nội dung, đối thủ và thời gian, nên Perxel không cam kết một vị trí xếp hạng cụ thể.\n\nFAQ\n\nSEO giúp website xuất hiện trong kết quả tìm kiếm của Google. GEO (Generative Engine Optimization) giúp nội dung được các công cụ AI như ChatGPT, Gemini hay AI Overviews đọc đúng và trích dẫn khi trả lời. Phần nền của hai việc này giống nhau: trang tải được, nội dung rõ ràng, cấu trúc trang mạch lạc và dữ liệu có cấu trúc đầy đủ. Google cũng cho biết các tính năng AI của họ dựa trên đúng những yêu cầu SEO cơ bản này.\n\nChưa đủ. Điểm này cho biết website không mắc các lỗi kỹ thuật cơ bản, như thiếu tiêu đề, thiếu mô tả hay chặn Google lập chỉ mục. Nó không đánh giá nội dung có trả lời đúng câu hỏi của khách hàng hay không, và cũng không kiểm tra hết mọi lỗi. Vì vậy Perxel xem 100 điểm SEO là mức tối thiểu khi bàn giao, còn sơ đồ trang và dữ liệu có cấu trúc mới là phần tạo khác biệt.\n\nPhần lớn trường hợp là được. Perxel kiểm tra website trước, rồi đề xuất chỉnh trên nền hiện tại nếu theme và plugin còn cho phép. Chỉ khi theme quá cũ hoặc page builder sinh ra quá nhiều mã thừa thì Perxel mới đề xuất viết lại theme, và khi đó vẫn giữ nguyên đường dẫn cũ để không mất thứ hạng.\n\nĐiểm chỉ giảm khi bài mới thiếu alt text cho ảnh hoặc dùng chữ chung chung như \"xem thêm\" cho đường dẫn. Trường alt text được đặt bắt buộc trong CMS, và Perxel hướng dẫn team nội dung cách đặt tiêu đề, mô tả và link nội bộ cho từng bài khi bàn giao.\n\nGoogle cần thời gian để lập chỉ mục lại các trang đã chỉnh, thường từ vài ngày đến vài tuần tùy quy mô website. Bạn theo dõi được quá trình này trong Google Search Console, Perxel sẽ thiết lập và bàn giao tài khoản cùng website.\n\nĐọc thêm\n\n- PageSpeed Insights & Core Web Vitals (/insights/pagespeed)\n- Website Next.js & Headless CMS (/services/nextjs)\n- Làm website WordPress custom theme (/services/wordpress-custom-theme)\n\nLiên hệ Perxel\n\n1. Chrome for Developers: Lighthouse SEO audits\n2. Google Search Central: Introduction to structured data\n3. Google Search Central: AI features and your website\n4. llms.txt"},{"kind":"service","locale":"en","slug":"wordpress-custom-theme","title":"WordPress Custom Theme Development","shortTitle":"WordPress Custom Theme","excerpt":"Boutique studio Perxel builds WordPress websites on custom themes written for each project, from company sites to WooCommerce online stores. Fast to load, easy to manage, with the whole codebase handed over.","categories":["WordPress"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"nectarblocks","label":"NectarBlocks"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/services/wordpress-custom-theme","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Perxel builds WordPress websites on a custom theme written for each project, following your Figma design. WordPress is the most widely used content management system, according to W3Techs. The business owns the codebase and the data, and picks the hosting that fits.\n\nOwn your digital assets\n\n- You own your data. Closed SaaS platforms charge a recurring subscription and control the infrastructure. With WordPress the business owns the codebase and the database, and chooses a hosting provider that fits the real budget.\n- Room to grow. WordPress is an open ecosystem. Marketing tools, a CRM, online payments or internal systems plug in as the business grows.\n- A good foundation for SEO. With Rank Math or Yoast SEO, WordPress lets you declare metadata, a sitemap and structured data for each page. The WordPress sites we built, such as Khatra Tile and Sundmd, all score 100 for SEO in PageSpeed. More on this in SEO & GEO for websites (/en/services/seo).\n\nA custom theme, written from scratch\n\nPerxel writes the theme from scratch for each website. It does not use ready-made themes from ThemeForest or other marketplaces.\n\nA flexible drag-and-drop editor\n\nThe drag-and-drop editor lets a business reuse ready-made design blocks to build new pages without touching code. Perxel keeps the input fields simple, makes visual editing easy and removes complicated settings.\n\nPerformance on real devices\n\nA custom theme leaves out the extra code that ready-made themes carry, so the site loads fast on mobile. Khatra Tile (/en/works/khatra), a site we built, passes Core Web Vitals on real-user data, mobile included.\n\nControl of the whole codebase\n\nPerxel controls the entire codebase and never uses pirated plugins. Together with an activity log for admin accounts, the business always knows what has been done in the system.\n\nAn easy admin experience\n\nPerxel uses NectarBlocks, a drag-and-drop tool built on Gutenberg, to create the page editing area for clients. After handover the team can add pages, rearrange layouts or update content in a visual editor, without calling a developer for every small change.\n\nEven though pages are assembled with a drag-and-drop tool, every detail of the Figma design is still coded by Perxel, with no ready-made templates. The result is easy to manage day to day and keeps the brand's own design identity.\n\nOnline stores with WooCommerce\n\nBeyond company websites, Perxel builds custom themes for online stores on WooCommerce, the standard e-commerce plugin in the WordPress ecosystem. Category pages, product pages, the cart and checkout are all coded to the Figma design, not left on the default WooCommerce look.\n\nThe business manages products, stock, promotions and orders in its own admin, with no revenue-based subscription fees like SaaS e-commerce platforms.\n\nSafety and security\n\nThe idea that WordPress is easy to attack is only part of the picture. WordPress core receives security patches regularly and quickly. Most real risk comes from installing too many free plugins of unknown origin, using pirated plugins or loose system settings.\n\nPerxel handles this with two clear principles:\n\nNo plugins of unknown origin\n\nPerxel only uses licensed premium tools that have been tested across many real projects: Gravity Forms for forms, WPML for multiple languages and NectarBlocks for block-based layouts on Gutenberg.\n\nSecurity set up from operating experience\n\n- Control and traceability. An activity log records installs, content edits and admin login history, so administrators can trace what happened when a problem appears.\n- Blocking intrusion. The default login URL is changed, IPs that probe for passwords are blocked automatically (brute-force protection) and a firewall limits form spam.\n\nA complete, simple handover\n\nPDF guides are long and easy to lose. Perxel hands over in a more visual way:\n\n- A Website Guide inside the admin. Perxel builds a user guide page inside the admin dashboard. Admins can open it at any time to see screenshots, video walkthroughs of real tasks and quick links to each admin feature, with no document to dig up.\n- Full ownership handed over. When the project ends, hosting account details, the domain and any third-party service accounts are handed to the client. The website is fully independent, with no technical tie to Perxel, and can move to an in-house team or any other partner at any time.\n\nWorking alongside creative agencies and designers\n\nPerxel works as a technical partner, not a passive outsourcer, and shares the designer's eye for aesthetics and design language.\n\nPerxel does not make promises like \"100% identical to the static design\". Instead, it discusses the design with the designer from the Figma sketch stage and gives the technical feedback that is needed, to handle responsive edge cases and find the most natural responsive behaviour. Working closely with Perxel also gives designers practical insight they can reuse in the design system for their next products.\n\nLower cost over the long run\n\n- No recurring platform subscription. The business owns the system and pays nothing per page, per language or per editor, unlike no-code tools.\n- Light to run on standard hosting. A lean custom codebase runs smoothly on standard hosting plans, with no complicated server setup.\n\nFAQ\n\nThe cost of a WordPress project depends on the number of pages, the number of blocks to build and features such as multiple languages or WooCommerce. Perxel quotes after reviewing the Figma file and agreeing the scope. Starting prices are on our pricing page (/en/pricing).\n\nCommercial themes are designed for thousands of different users, so they carry a lot of extra code to cover every possible feature. That makes a site heavy, slow and hard to customise deeply. A custom theme at Perxel is written for your actual needs and your Figma design. Your interface is one of a kind, light, smooth to run and easy to upgrade later.\n\nThey can. With the NectarBlocks page builder on Gutenberg, editors use blocks that Perxel has already built to create new pages such as campaign landing pages or articles. Responsive rules, spacing and fonts are fixed in the codebase, so new pages come out clean and consistent without hiring a developer to fix them.\n\nSecurity is set up while the codebase is written, based on real operating experience. An activity log records admin logins and actions, so you can control the whole system. The default login URL is changed, brute-force protection locks out IPs that guess passwords and a firewall is configured against spam. Perxel does not use pirated plugins.\n\nPerxel provides the licences for the core premium plugins in the initial build: Gravity Forms, WPML and NectarBlocks. After handover the business only pays its own domain and hosting providers, with no hidden subscription from Perxel.\n\nPerxel does. Beyond company websites, Perxel builds custom themes for WooCommerce stores, including category pages, product pages, the cart and checkout. The interface is coded to the Figma design, not the default WooCommerce theme.\n\nIt can. The codebase is organised cleanly and follows current WordPress best practice, so the site works well with future technology. Perxel can add specialised features or write extra custom plugins for the existing system at any time, without rebuilding the whole website.\n\nAfter testing across devices and browsers, Perxel hands over in person together with the Website Guide inside the admin. All code and all accounts are transferred. You do not depend on Perxel and can pass the site straight to an in-house technical team. Perxel also provides technical maintenance for the term agreed in the project.\n\n1. W3Techs: Usage statistics of WordPress\n2. NectarBlocks\n3. Gravity Forms\n4. WPML"},{"kind":"service","locale":"en","slug":"wordpress-plugins","title":"WordPress Plugin Development","shortTitle":"WordPress Plugins","excerpt":"Boutique studio building WordPress plugins to official standards. They solve operational problems, sync data through APIs and automate the system.","categories":["WordPress"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/services/wordpress-plugins","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"A website that works well takes manual operating work off a business. As a system grows, patching it together with dozens of third-party plugins tends to cause technical conflicts, slow real page loads and raise security risk.\n\nPerxel's custom plugin service keeps the system lean by writing dedicated code for each specific business requirement. The focus is on automating repetitive work, to save staff time and day-to-day running cost.\n\nWhat you get from plugins built at Perxel\n\nA consistent admin experience\n\nPerxel uses the wp-plugin-ui interface kit for all its products. It is a shared UI kit that keeps the display consistent, so the admin experience stays friendly, clear and in step with the WordPress design style.\n\nCompatibility standards\n\nEvery plugin Perxel builds follows the WordPress Coding Standards and the Plugin Developer Handbook. This keeps plugins compatible over the long term when WordPress core is upgraded, and cuts technical conflicts.\n\nAssessment before integration\n\nPerxel's custom plugins work best on websites that use a custom theme built by Perxel. For sites running on other themes, Perxel reviews the structure of the system first and proposes a safe, effective way to integrate.\n\nSolutions already delivered\n\n- A public plugin for the community. Perxel built and shares the ACF IcoMoon plugin in the official WordPress directory. It helps developers add and manage custom icon fields through Advanced Custom Fields.\n- AI translation automation. An open-source plugin on GitHub connects directly to an AI API to automate multilingual translation. On a project that needed more than 800 products translated, Perxel ran the translation through the API for under USD 8 and finished all the data in 2 weeks.\n- Automatic image optimisation. A dedicated plugin compresses and optimises images as they are uploaded to the admin, so the website stays fast without a recurring paid image compression service.\n\nFAQ\n\nExisting plugins are usually written for the common needs of thousands of users, so they carry extra features that slow a website down or cause conflicts. A custom plugin at Perxel is written lean from the ground up to solve one need, or a group of needs, that is specific to you. The code stays minimal, performance is better and the result is safer.\n\nIt should not. Perxel's plugins follow the official coding standards and use the standard APIs WordPress provides, so they stay compatible and run steadily through core updates.\n\nIt can. Perxel writes dedicated custom plugins to connect a website with internal systems such as a CRM, an ERP, payment gateways or third-party API services, so data moves through the process automatically and smoothly.\n\nContact Perxel\n\n1. wp-plugin-ui\n2. WordPress Coding Standards\n3. Plugin Developer Handbook\n4. ACF IcoMoon"},{"kind":"service","locale":"en","slug":"web-animation","title":"Web animation","shortTitle":null,"excerpt":"Boutique tech studio that brings static designs into the browser with natural motion and micro-interactions, with page-load performance tuned from real project experience.","categories":["Animation"],"tech":[{"id":"gsap","label":"GSAP"},{"id":"motion","label":"Motion"},{"id":"lottie","label":"Lottie"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/services/web-animation","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Every website project at Perxel is its own operating problem. Some clients want brand storytelling, like Tam Coc Garden or Sun DMD. Some partners put stability and polish first, like REE, Long An International Port or RMIT. And some want both, like Huynchi or Tuan Loc Commodities.\n\nAfter years of serving clients across many industries and countries at large agencies, Perxel balances these needs with real experience of the web. That shows up as the technical feedback that is needed when working with the designer from the very first steps. Static designs reach the browser through motion and micro-interactions that add depth to the site while keeping its performance intact.\n\nThree core values\n\nBalancing art and operation\n\nPerxel understands what each brand needs. It balances the brand story against the stability and polish a large company expects, and delivers interaction that fits the context.\n\nTechnical feedback where it is needed\n\nPerxel works closely with the designer from the Figma sketch stage. It gives feedback on whether a motion is feasible, handles gaps in the design and proposes responsive behaviour.\n\nA flexible choice of technology\n\nPerxel does not depend on one tool. It mixes GSAP, CSS, plain JavaScript and lean libraries as the project needs, and even writes its own code for a project so the site loads as fast as it can.\n\nFlexible tools, a lean codebase\n\nComplex 2D motion is built with GSAP for precise control of the timeline. But instead of leaning on a single tool, Perxel's advantage is using different solutions as a project requires.\n\nFor basic motion, Perxel prefers CSS animation or plain JavaScript to keep the site as light as possible. In many cases an ultra-lean library such as motion is chosen to protect page-load performance.\n\nFor projects that need the most performance and no extra code, Perxel builds its own animation libraries, such as cuajs (motion) and scroll-snooper (scroll interaction), shared publicly on GitHub.\n\nFor animated illustrations such as icons, Perxel uses Lottie: the files are light, sharp and can take the brand colours.\n\nCompatibility from experience\n\nTesting on a wide range of real mobile devices is an important quality standard in the industry, and it keeps the display consistent. Perxel's experience across hundreds of varied projects means it knows which effect pairs with which technique, so a website displays steadily in most browsers and on most users' devices.\n\nPerxel always sets up responsive animation with care. It adjusts or simplifies effects automatically when a device has limited hardware, to avoid stutter and overheating, so scrolling feels natural.\n\nFAQ\n\nMotion only slows a site when the code is careless or heavy libraries are piled on. With a minimal approach and the ability to write its own code, like scroll-snooper and cuajs, Perxel plans the build so the site reaches good practical performance: smooth, and still fast to load.\n\nFrom experience with responsive animation, Perxel knows how to simplify or adjust effects for touch and swipe on mobile, which keeps behaviour consistent and stable over time.\n\nIt can. As a technical partner working with motion since 2016, Perxel proposes a rhythm of movement based on your brand's personality, then discusses it with the designer to bring it to life.\n\nIt will not. Perxel's custom codebase keeps content data fully separate from the motion logic. You can change text and images freely in the admin without affecting the effects that were built.\n\nContact Perxel\n\n1. GSAP\n2. Motion\n3. Perxel on GitHub"},{"kind":"service","locale":"en","slug":"nextjs","title":"Next.js & Headless CMS Websites","shortTitle":"Next.js & Headless CMS","excerpt":"Boutique tech studio building websites on Next.js with a headless CMS (TinaCMS, Prismic). Fast page loads at the edge, visual editing and full control of running costs.","categories":["Next.js"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"prismic","label":"Prismic"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/services/nextjs","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"For marketing campaigns, product landing pages and modern company websites, what matters most is delivery speed, instant page loads and low running costs. Without a heavy CMS or a complicated server, Next.js with a headless CMS strikes a good balance: a proper React frontend, a visual editing interface for the marketing team and smooth delivery from the edge, with no monthly upkeep cost.\n\nTechnical advantages of Next.js\n\nNext.js combines modern React with flexible rendering (server-side rendering and static generation). The whole frontend, the SEO metadata logic, image optimisation and the small API endpoints live in one clearly structured codebase.\n\n- Instant page loads at the edge. On a global CDN (Cloudflare Workers through OpenNext), the site responds almost immediately, with a TTFB under 50ms, and does not depend on a traditional web server.\n- Frontend separate from content management. Developers can build visuals and micro-interactions that follow Figma closely, without the limits of a traditional CMS template.\n- Ready to grow into a web app. When a business needs a dashboard, a payment gateway or a link to internal APIs, the Next.js codebase can take it without restructuring the whole system.\n\nTwo headless CMS options\n\nEvery business has a different amount of content and a different way of working. Perxel focuses on the two headless CMS options that fit and run best with Next.js today:\n\nPrismic\n\nPrismic is a commercial headless CMS with a modern admin, designed as a page builder based on Slices. It lets the marketing team arrange content layouts without breaking the original design.\n\nThe free plan covers 1 editor account, 2 languages and 100GB of bandwidth a month. When you need more, the Starter plan at about $10 a month raises that to 3 editor accounts and 3 languages, which suits most company websites and standard landing pages.\n\nTinaCMS\n\nTinaCMS is an open-source headless CMS that works on a Git-backed model: content is stored in the project's own repository rather than in a separate database. As a result a website has no limit on the number of languages and no bandwidth-based fees. TinaCMS is known for click-to-edit directly on the page.\n\nThe free plan covers 2 editor accounts and unlimited languages. When the editing team grows, the Team plan at about $24 a month raises that to 3 editor accounts. For most websites run by one or two content owners, the free plan is enough.\n\nChoosing by how the site will be run\n\nFrom real projects, Perxel suggests an approach for each situation:\n\n- Pick Prismic when you need a full-featured CMS. It suits most company websites and landing pages that need flexible content modelling, a clear publishing workflow or fewer than 3 languages.\n- Pick TinaCMS when cost and click-to-edit matter most. It suits sites that need 3 or more languages or have high traffic and should not pay CDN bandwidth fees.\n\nProjects already in production\n\nPerxel's Next.js and headless CMS work comes from real products and case studies:\n\n- Atlas Robotics (TinaCMS). A multilingual B2B marketing website (English, Vietnamese, Chinese) that handles large media files and runs smoothly on Cloudflare Workers at a server cost of $0 a month.\n- Foldables (Prismic). Content modelling with the Prismic CLI, Slice Machine setup and instant content revalidation through webhooks on Cloudflare Workers.\n- Growtrics (TinaCMS). A marketing website for an EdTech startup in Singapore, with TinaCMS built in and handed over in 3 working days. See Growtrics (/en/works/growtrics).\n- Official certification. Perxel's lead engineer is a TinaCMS Certified Developer, certified by the TinaCMS team itself.\n\nNext.js and WordPress compared\n\nBoth platforms serve marketing websites well. The cost gap between them is not large in practice, but each has its own architectural strengths:\n\n- Next.js infrastructure advantage: static deployment on Cloudflare Workers' free plan keeps hosting cost low for small and mid-sized websites.\n- Room to grow: Next.js is built on React, so it is more flexible when you need to go deeper later, such as your own API, a CRM link or a specific business system.\n- When to choose which: choose Next.js if you plan to grow the website into a web app or need deep integration with third-party services. Choose WordPress when the site mainly serves information; Perxel's WordPress custom theme service (/en/services/wordpress-custom-theme) offers a comparable editing experience and performance.\n\nA technical partner for agencies and businesses\n\nPerxel works as a technical partner with an eye for aesthetics, not as a passive code vendor.\n\nThe design intent from Figma, kept\n\nEvery interface block is turned into a proper React component that keeps the grid proportions and typographic rhythm of the design, and displays steadily across devices and browsers.\n\nFull ownership of codebase and infrastructure\n\nThe whole codebase in a Git repository, the Cloudflare hosting account, the domain and related service accounts are all handed over. The website is fully independent, with no technical tie to Perxel.\n\nLower running cost over the long run\n\nWith static and edge rendering, the website needs no high-spec server or costly database. The business saves on monthly hosting and keeps page loads fast.\n\nFAQ\n\nThey can. Both Prismic and TinaCMS offer a visual editor with live preview or drag-and-drop blocks. Content owners can update text, swap images and arrange blocks on a page without touching code.\n\nA static Next.js site with a headless CMS has no complicated plugin system and no database holes that need regular patching, as traditional CMSs do. After handover you can keep managing content on your own. A developer is only needed when you want a new feature, a new block or a change to the design structure.\n\nIt does not. Neither Prismic nor TinaCMS caps the number of pages or posts by storage fees. That is convenient for marketing campaigns that keep producing new landing pages.\n\nIt does. Multiple languages can be set up fully, from the URL structure and the content in the CMS to the interface. TinaCMS's free plan supports unlimited languages, while Prismic's free plan supports up to 2.\n\nPerformance and SEO are the core advantages of this stack. Pages are pre-rendered as static HTML and served from Cloudflare's edge CDN, so responses are instant with a TTFB under 50ms. Next.js also gives full control over meta tags, Open Graph and structured data for each page. The Next.js sites we built, such as Foldables and Atlas Robotics, all score 100 for SEO in PageSpeed. More on this in SEO & GEO for websites (/en/services/seo).\n\nWebflow and Framer cost less up front when you build with no-code tools yourself. But as a website grows in traffic, pages or languages, the monthly subscription of a no-code platform climbs quickly. Next.js with a headless CMS needs development cost at the start, and in return you own the codebase and keep monthly running cost minimal.\n\nIt can. Perxel works behind creative agencies and designers, taking on frontend development, CMS integration and infrastructure. The agency keeps working directly with its own client. See Website Development Partner (/en/services/development-partner).\n\nIt can. The component architecture of React and Next.js fits design-system workflows naturally. Perxel can follow an agency's design tokens, coding standards and existing component library exactly.\n\nRequest a demo\n\n1. Next.js\n2. TinaCMS\n3. TinaCMS: Pricing\n4. Prismic\n5. Prismic: Pricing\n6. Cloudflare Workers: Pricing"},{"kind":"service","locale":"en","slug":"development-partner","title":"Website Development Partner","shortTitle":"Development Partner","excerpt":"Boutique tech studio working alongside creative agencies and freelance designers, building websites from Figma designs with real technical feedback and professional white-label support.","categories":["Technical consulting"],"tech":[{"id":"figma","label":"Figma"},{"id":"github","label":"GitHub"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/services/development-partner","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"An excellent design in Figma is only complete once it reaches the browser with the right proportions, a natural interaction rhythm and steady performance. A close link between the designer's sense of aesthetics and the engineer's coding ability is what makes a project work.\n\nPerxel works closely with creative agencies and freelance designers as an extension of their technical side. It shares the designer's eye for aesthetics so it understands your design language, helps solve complex coding problems and takes the technical pressure off so you can focus on your creative strengths.\n\nWhat working with Perxel gives you\n\nLower cost for mobile design\n\nPerxel builds every mobile design the designer provides. When an agency wants to cut design cost, Perxel can also work out natural responsive behaviour from the desktop design and still make sure the website displays well.\n\nConfidentiality and white label\n\nPerxel offers white-label service and signs an NDA. Code and anything displayed at handover to the end client carries the agency's own branding, so everything stays consistent and professional.\n\nNatural interaction\n\nWith deep experience in web animation and web interaction, Perxel adds natural interaction and fine micro-interactions that bring a static design to life without hurting load speed.\n\nHow the collaboration runs\n\nPerxel joins the discussion as soon as the brief arrives or the sketch is taking shape. It answers technical questions, assesses feasibility, proposes approaches and clarifies the project scope.\n\nClean code written to established coding standards, with Perxel's own UI kits for a good admin experience.\n\nPerxel takes feedback directly from both the agency and the agency's end client, and makes the adjustments needed for the website to reach its best before going live.\n\nThe complete codebase is handed over with detailed guidance, so the website keeps running steadily.\n\nFAQ\n\nPerxel signs NDAs to protect project information and offers white-label service. Code, contact details and what shows in the admin all carry the agency's branding, so everything stays consistent in front of partners and end clients.\n\nWhen an agency wants to reduce the cost of designing and building mobile screens, Perxel can build the mobile interface itself, staying close to the design language of the desktop version. Designing and coding many separate screens adds cost in proportion, so this saves the agency budget. For pages with complex storytelling or a very specific layout, Perxel recommends drawing a separate mobile design.\n\nPerxel hands over the whole clean codebase and helps the agency set the website up in its live environment, with detailed admin guidance, so the site runs steadily before it goes to the end client.\n\nContact Perxel"},{"kind":"service","locale":"en","slug":"ai-solutions","title":"AI Solutions & System Integration","shortTitle":"AI Solutions","excerpt":"Boutique tech studio building the API layer and MCP protocol that connect AI to business data, with help managing API keys, budgets and quality monitoring to technical standards.","categories":["AI"],"tech":[{"id":"chatgpt","label":"ChatGPT"},{"id":"claude","label":"Claude"},{"id":"gemini","label":"Gemini"},{"id":"openrouter","label":"OpenRouter"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/services/ai-solutions","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Bringing AI (ChatGPT, Claude, Gemini) into a company's operations is more than dropping in a ready-made chat window or installing a packaged automation plugin. Leaning on packaged tools often brings dependence on third-party infrastructure, leaks of internal data and API costs that are hard to control.\n\nStart with the operating architecture\n\nPerxel approaches AI solutions as a technical partner, focused on building a dedicated API layer and applying the MCP protocol (Model Context Protocol). Whether it builds on an existing platform such as WordPress or on a standalone Next.js application, Perxel works on a pay-for-what-you-use basis, so the business keeps its budget in check and full ownership of its digital assets.\n\nThree pillars of AI work at Perxel\n\n- A flexible architecture. Perxel puts chatbots and AI directly on existing data (WordPress, Next.js) when the structure is clean enough. When needed, it builds a standalone system and syncs data both ways to keep operations efficient.\n- Cost that follows real use. Connect through an AI gateway such as OpenRouter or call APIs directly, with a measuring tool such as Langfuse to keep answer quality and budget transparent.\n- Ownership and governance. The business holds the API key account. Perxel helps set budget limits and hands over clean code, with no recurring licence fee.\n\nWhat gets built\n\nAPI layer and MCP layer\n\nAn intermediate API layer and the MCP protocol let AI models query company data safely in real time. This model already runs in production through the OpenWallet (/en/works/openwallet) project, which gives the Owie AI assistant and external AI tools structured bank card data through a dedicated MCP server.\n\nChatbots on company data\n\nWordPress is a typical data source for a chatbot built directly on top, when the structure is clean enough. For more complex systems, Perxel builds the chatbot on Next.js or as a standalone system with two-way data sync, to keep it safe and fast.\n\nAutomating large-scale data processing\n\nAI applied to operating problems with a large amount of data. On the Khatra Tile project (/en/works/khatra), Perxel built the Perxel AI Translate plugin to translate close to 1,000 posts and products into English, with pay-for-what-you-use API costs far below fixed-fee services.\n\nAI governed to technical standards\n\nEvery query is traced through Langfuse, answer accuracy is evaluated, replies that fall short are flagged and prompts are tuned continuously.\n\nThe business holds the API key account. Perxel helps set spending limits (budget caps) and automatic alerts so running costs stay within reach.\n\nConnect through a familiar AI gateway such as OpenRouter, or work directly with the APIs of the model providers (OpenAI, Anthropic, Google), billed on the tokens actually used.\n\nWhen it fits\n\n- When a business wants a chatbot or AI connected directly to its existing operating data.\n- When a standard API or MCP layer is needed so an AI assistant can query data safely.\n- When the volume of content to process (translation, summarising) is large enough that API automation costs less than a fixed-fee service.\n- When the API budget needs close monitoring and control instead of being left to a packaged provider.\n\nFAQ\n\nPackaged services usually charge a fixed monthly licence and keep data on a third-party server. Perxel's approach is pay-for-what-you-use through APIs, with a budget limit to control cost and a dedicated codebase handed over to the business.\n\nPerxel puts a chatbot directly on existing WordPress or Next.js data when the data is clean enough. When operations need to be separate for safety and performance, Perxel builds a standalone AI system and sets up automatic data sync.\n\nPerxel sets up AI observability (such as Langfuse) to trace and measure the quality of each answer. Together with MCP standardising the input data, the system only reads from the data stores it is given access to, which limits wrong answers.\n\nThe business owns the API key account. Perxel helps manage it: setting spending limits, tracking token use and raising alerts in time so the system keeps running steadily.\n\nContact Perxel\n\n1. OpenRouter\n2. Langfuse"},{"kind":"service","locale":"en","slug":"seo","title":"SEO & GEO for Websites","shortTitle":"SEO & GEO","excerpt":"Perxel builds the page structure around what your clients actually search for, so Google ranks it and AI tools like ChatGPT and Gemini read and cite it correctly. Handed over with a 100 SEO score in PageSpeed, on your current site or a new one.","categories":["Technical consulting"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"nextjs","label":"Next.js"},{"id":"pagespeed","label":"PageSpeed Insights"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/services/seo","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Before a page can rank, Google has to read it: what it is about, which group of content it belongs to and which other pages it relates to. AI tools like ChatGPT, Gemini and Google's AI Overviews read a site the same way before they cite it. That work lives in the code and the page structure, so we do it while we build, on WordPress and Next.js alike.\n\nWhat we commit to at handover\n\nA 100 SEO score in PageSpeed at handover\n\nThe homepage, service pages, product pages and articles are all checked with Lighthouse on mobile and desktop before handover. Measured on 13 October 2026 with Lighthouse 12, perxel.com, Khatra Tile (/en/works/khatra), Sundmd, Foldables (/en/products/foldables) and Atlas Robotics (/en/products/atlas-robotics) all scored 100 for SEO on both mobile and desktop.\n\nPageSpeed Insights on mobile for five sites built by Perxel, measured 13 October 2026.\n\nTwo parts of the score are written by whoever edits the content after handover: image descriptions (alt text) and link text. So we make alt text a required field in the CMS, and the score holds as new posts go in.\n\nPage structure built around what clients search for\n\nWe map the pages before we write any code: each page targets one main search term, and related pages link to each other in the order a reader needs them. Google understands which topics the site covers, and readers move from page to page along a clear path instead of going back to the homepage.\n\nStructured data for Google and AI\n\nBusiness details, address, products, articles and breadcrumbs are declared as structured data (JSON-LD). Multilingual sites get hreflang tags so Google shows each reader the right version. An llms.txt file also summarises the site so AI tools can read its main content quickly.\n\nGEO: getting AI tools to read and cite your site\n\nGEO (Generative Engine Optimization) is the work that helps ChatGPT, Gemini, Perplexity and Google's AI Overviews read your content correctly and mention it in their answers. The technical SEO above is the foundation; on top of it we do four things:\n\n- Let AI bots in. We check robots.txt, Cloudflare and hosting settings so GPTBot, ClaudeBot and PerplexityBot aren't blocked or rate-limited without you knowing. Many hosting plans and firewalls ship with rules that block bots, so this needs checking on every site.\n- Write content AI can quote. Each page answers its main question in the first paragraph, with clear headings, an FAQ section, and figures that carry a date and a source.\n- A source for machines. Beyond JSON-LD and llms.txt, a Next.js site can also publish a JSON feed or an MCP server. Our own site uses that same source for Ask Perxel, the assistant that answers visitors.\n- Measure traffic from AI. Visits from chatgpt.com, perplexity.ai and gemini.google.com get their own channel in Google Analytics, so you can see whether GEO brings in visitors.\n\nYour current site or a new one\n\nIf your current site can still be worked on, we keep it. On Khatra Tile (/en/works/khatra), a WordPress site more than 10 years old with close to 800 products, we rewrote the whole theme but kept every URL, so rankings for the key search terms in the tile industry held steady after the new design launched.\n\n- WordPress sites. We configure Rank Math or Yoast SEO and fix the parts of the theme the plugin can't reach. Khatra Tile uses Rank Math to declare the business address and coordinates, in Vietnamese and English. Sundmd uses Yoast SEO for breadcrumbs and an automatic llms.txt.\n- Next.js sites. Metadata, the sitemap, structured data and llms.txt are written in code, so they always match what is in the CMS. Our own site also has a JSON feed and an MCP server, so AI tools can read the full content without guessing from the layout.\n\nHow we work\n\n1. Audit the current site. Measure the SEO score and check the sitemap, canonical URLs, structured data, which pages Google has indexed in Search Console, and whether AI bots can reach the site.\n2. Map pages and search terms. Each page gets one main search term, a clear purpose and a list of the pages it links to. You approve the map before we start on the code.\n3. Build. Adjust page structure, metadata, structured data and internal links on your current site, or build a new one from the approved map.\n4. Test and hand over. Run Lighthouse on every page type, submit the sitemap to Google Search Console and show your content team how to keep these checks passing when they publish.\n\nEvery site has its own size and starting point, so we send a quote after the first audit.\n\nScope\n\nWe handle the technical foundation and the structure of the site. Ongoing content writing and link building aren't part of this service. Rankings on Google and citations by AI tools also depend on content, competitors and time, so we don't promise a specific ranking.\n\nFAQ\n\nSEO helps a site show up in Google's search results. GEO (Generative Engine Optimization) helps AI tools like ChatGPT, Gemini and AI Overviews read your content correctly and cite it in their answers. The foundation is the same for both: pages that load, clear content, a sensible page structure and complete structured data. Google says its AI features rely on exactly these SEO basics.\n\nOn its own, it isn't. The score tells you the site avoids basic technical mistakes, like a missing title, a missing description or blocking Google from indexing. It doesn't judge whether your content answers your clients' questions, and it doesn't catch every issue. We treat 100 as the minimum at handover; the page map and structured data are what make the difference.\n\nIn most cases you can. We audit the site first, then suggest changes on top of what is there if the theme and plugins allow it. We only suggest rewriting the theme when it is too old or the page builder produces too much bloated markup, and even then we keep the old URLs so you don't lose rankings.\n\nIt only drops if a new post has images without alt text or vague link text like \"read more\". Alt text is a required field in the CMS, and at handover we show your content team how to write titles, descriptions and internal links for each post.\n\nGoogle needs time to re-index the pages we changed, usually from a few days to a few weeks depending on the size of the site. You can follow this in Google Search Console, which we set up and hand over with the site.\n\nFurther reading\n\n- PageSpeed Insights & Core Web Vitals (/en/insights/pagespeed)\n- The SEO score in PageSpeed (/en/insights/seo-score)\n- GEO: helping ChatGPT and Gemini read your website (/en/insights/geo)\n- Next.js & Headless CMS websites (/en/services/nextjs)\n- WordPress custom theme development (/en/services/wordpress-custom-theme)\n\nContact Perxel\n\n1. Chrome for Developers: Lighthouse SEO audits\n2. Google Search Central: Introduction to structured data\n3. Google Search Central: AI features and your website\n4. llms.txt"}],"insights":[{"kind":"insight","locale":"vi","slug":"claude-for-startups","title":"Perxel được duyệt vào Claude for Startups","shortTitle":null,"excerpt":"Perxel được Anthropic duyệt vào chương trình Claude for Startups, gồm API credit, một năm Claude Team và các ưu đãi từ những công ty xây dựng sản phẩm trên Claude.","categories":["Development"],"tech":[{"id":"claude","label":"Claude"}],"date":"2026-10-13","updated":null,"dateModified":"2026-10-13","url":"https://perxel.com/insights/claude-for-startups","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Ngày 10/10/2026, Perxel được Anthropic duyệt vào chương trình Claude for Startups, chương trình dành cho các startup xây dựng sản phẩm trên Claude, model AI của Anthropic.\n\nTheo email từ team Claude Startups, đợt này chương trình nhận số đơn đăng ký gấp 21 lần tổng số đơn trong 5 tháng hoạt động trước đó, nên mỗi hồ sơ đều được xét duyệt lại trước khi xác nhận.\n\nEmail xác nhận từ team Claude Startups.\n\nChương trình gồm những gì\n\nThành viên của chương trình nhận các ưu đãi sau (điều kiện và giá trị cụ thể nằm ở trang chương trình):\n\n- API credit để chạy Claude qua Claude API. Credit chỉ dùng được trên API của Anthropic, không dùng qua AWS Bedrock hay Google Vertex AI.\n- Một năm Claude Team cho những team chưa dùng gói Team trước đó.\n- Startup Stack: ưu đãi và credit từ các công ty AI khác xây dựng sản phẩm trên Claude, đổi bằng mã trong Claude Console.\n- Rate limit API cao hơn và buổi trao đổi hai tuần một lần với team Applied AI của Anthropic.\n\nPerxel đang dùng Claude ở đâu\n\nClaude đã có mặt trong sản phẩm của Perxel từ trước khi tham gia chương trình:\n\n- Ask Perxel trên chính website này. Khi bạn nhấn ⌘K (hoặc nút Ask Perxel) rồi đặt câu hỏi, câu trả lời được Claude Haiku viết từ nội dung của website, kèm nguồn để bạn mở lại trang gốc. Khung tìm kiếm và chat này được Perxel đóng gói thành package @perxel/spotlight trên npm.\n- Perxel AI Translate (/products/perxel-ai-translate), plugin WordPress dịch hàng loạt bài viết WPML bằng model AI bạn chọn qua OpenRouter, trong đó có Claude.\n\nÝ nghĩa của chương trình với Perxel\n\nPerxel là một web tech studio làm việc theo hướng AI-native: 7 năm kinh nghiệm làm web được kết hợp với AI trong công việc hằng ngày, để mỗi ý tưởng đi từ bản thử đến sản phẩm hoàn thiện nhanh hơn.\n\nVì vậy, với Perxel, chương trình này không chỉ là một khoản sử dụng Claude miễn phí. Phần chi phí được giảm bớt giúp Perxel:\n\n- Thử nghiệm nhiều hơn trước khi chọn giải pháp cho một dự án.\n- Làm thêm sản phẩm của riêng mình, như các plugin và công cụ trong mục Sản phẩm (/products).\n- Rút ngắn vòng lặp từ ý tưởng, bản thử đến bản hoàn thiện.\n- Nâng kỹ năng dùng AI của cả team, rồi đưa những gì học được vào dự án của khách hàng.\n\nVới một startup như Perxel, khoản chi phí chương trình giúp cắt giảm là rất lớn. Perxel chân thành cảm ơn Anthropic và team Claude Startups.\n\nNếu bạn muốn website của mình có một trợ lý trả lời từ chính nội dung của bạn như Ask Perxel, hãy trao đổi với Perxel (/contact).\n\n1. Claude for Startups program (Anthropic)"},{"kind":"insight","locale":"vi","slug":"seo-score","title":"Điểm SEO trên PageSpeed","shortTitle":null,"excerpt":"Điểm SEO trên PageSpeed Insights kiểm tra mười lỗi kỹ thuật cơ bản. Năm website Perxel lập trình đều đạt 100, nhưng một trong số đó vẫn có lỗi canonical mà điểm số không phát hiện. Bài viết giải thích điểm này đo gì, bỏ sót gì và cách giữ điểm sau khi bàn giao.","categories":["SEO","Development"],"tech":[{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"wordpress","label":"WordPress"},{"id":"nextjs","label":"Next.js"}],"date":"2026-10-13","updated":null,"dateModified":"2026-10-13","url":"https://perxel.com/insights/seo-score","visibility":"public","deliveredByPerxel":true,"related":["geo","pagespeed"],"projects":["khatra","perxel-website"],"usedBy":[],"links":[{"caption":"Dịch vụ","title":"SEO và GEO cho website","href":"/services/seo"}],"body":"Trong báo cáo PageSpeed Insights, bên cạnh điểm Performance còn có ba điểm khác: Accessibility, Best Practices và SEO. Điểm SEO thường ít được để ý vì phần lớn website đều đạt khá cao, nhưng đây lại là điểm duy nhất Perxel cam kết đạt 100 khi bàn giao. Bài viết này giải thích điểm SEO kiểm tra những gì, kết quả đo trên năm website Perxel đã lập trình, những gì điểm số không phát hiện được, và cách giữ điểm khi website có thêm nội dung mới.\n\nĐiểm SEO kiểm tra những gì\n\nĐiểm SEO do Lighthouse chấm, gồm các mục kiểm tra sau:\n\n- Trang cho phép Google lập chỉ mục. Không có thẻ noindex hay quy tắc trong robots.txt chặn trang. Mục này có trọng số lớn nhất, vì một trang bị chặn thì các mục còn lại không còn ý nghĩa.\n- Trang có tiêu đề và mô tả. Thẻ và thẻ meta description là phần Google thường hiển thị trong kết quả tìm kiếm.\n- Trang trả về mã HTTP thành công. Một trang lỗi 404 hay 500 không được lập chỉ mục.\n- Link có chữ rõ nghĩa và Google đọc được. Chữ trên link nói được trang đích là gì (không phải \"xem thêm\"), và link là thẻ có href thật thay vì một nút chạy bằng JavaScript.\n- File robots.txt hợp lệ. Không có dòng sai cú pháp khiến Google hiểu nhầm.\n- Ảnh có alt text. Mô tả ngắn cho từng ảnh, giúp Google và trình đọc màn hình hiểu ảnh nói về điều gì.\n- Thẻ hreflang và canonical hợp lệ. Với website nhiều ngôn ngữ, mỗi phiên bản trỏ đúng sang các phiên bản còn lại, và mỗi trang khai báo một đường dẫn chính thức.\n\nKhác với Performance, các mục này không phụ thuộc vào máy đo hay tốc độ mạng. Một website làm đúng sẽ đạt cùng một điểm SEO ở mọi lần đo, nên đây là con số có thể cam kết được.\n\nKết quả trên năm website Perxel lập trình\n\nNgày 13/10/2026, Perxel đo trang chủ của năm website, gồm hai website WordPress và ba website Next.js, trên PageSpeed Insights bản mobile và bằng Lighthouse 12 trên cả mobile lẫn desktop. Tất cả đều đạt 100 điểm SEO.\n\nKết quả PageSpeed Insights bản mobile, đo ngày 13/10/2026. Điểm Performance thay đổi theo từng lần đo, điểm SEO thì không.\n\n- Website Perxel (/works/perxel-website) (Next.js). Metadata, sitemap và dữ liệu có cấu trúc được viết trong code, kèm thẻ hreflang cho hai phiên bản tiếng Việt và tiếng Anh.\n- Khatra Tile (/works/khatra) (WordPress). Website hơn 10 năm tuổi, dùng Rank Math để khai báo metadata, sitemap và thông tin doanh nghiệp.\n- Sundmd (WordPress). Website mới dựng bằng NectarBlocks, dùng Yoast SEO cho metadata, breadcrumb và sitemap.\n- Foldables (/products/foldables) và Atlas Robotics (/products/atlas-robotics) (Next.js). Hai bộ khung marketing website dùng Prismic và TinaCMS, phần SEO nằm trong code giống website Perxel.\n\nHai website WordPress đạt 100 nhờ plugin SEO được cấu hình đúng và theme không làm hỏng những gì plugin khai báo. Ba website Next.js đạt 100 vì mọi thẻ được sinh ra từ cùng một nguồn dữ liệu với nội dung trang, nên không có trang nào bị bỏ sót.\n\nNhững gì 100 điểm SEO không phát hiện được\n\nTrong lúc kiểm tra năm website trên, Perxel phát hiện Atlas Robotics có một lỗi mà Lighthouse không bắt được: mọi đường dẫn canonical và mọi URL trong sitemap đều có hai dấu gạch chéo, như atlas-robotics.perxel.com//about, và sitemap còn liệt kê cả trang 404. Nguyên nhân là biến môi trường chứa địa chỉ website có thêm dấu / ở cuối. Lighthouse chỉ kiểm tra canonical có hợp lệ hay không, còn một URL có hai dấu gạch chéo vẫn hợp lệ về cú pháp, nên điểm vẫn là 100. Lỗi này đã được sửa trong code bằng cách bỏ dấu / thừa trước khi ghép đường dẫn.\n\nNgoài các lỗi như vậy, điểm SEO còn bỏ qua ba phần quan trọng:\n\n- Dữ liệu có cấu trúc không được chấm điểm. Lighthouse có liệt kê mục này nhưng chỉ nhắc kiểm tra thủ công. Để biết JSON-LD có đúng hay không, cần dùng Rich Results Test của Google.\n- Lighthouse chỉ đo một trang mỗi lần. Trang chủ đạt 100 không có nghĩa trang sản phẩm hay bài viết cũng vậy. Perxel kiểm tra từng loại trang trước khi bàn giao, vì mỗi loại dùng một template riêng.\n- Cấu trúc trang và từ khóa nằm ngoài phạm vi. Điểm số không biết website có những trang nào, mỗi trang nhắm cụm từ khóa gì và các trang dẫn link sang nhau ra sao. Đây là phần quyết định Google hiểu website nói về chủ đề gì, và cũng là phần khách hàng thường hỏi nhiều nhất khi làm lại website.\n\nGiữ 100 điểm SEO sau khi bàn giao\n\nTrong các mục kiểm tra, có hai mục phụ thuộc vào người biên tập nội dung chứ không phụ thuộc vào code: alt text của ảnh và chữ trên link. Một bài viết mới với ảnh thiếu mô tả hay một nút \"xem thêm\" là đủ làm điểm giảm xuống.\n\n- Đặt trường alt text bắt buộc trong CMS. Với website Next.js dùng TinaCMS hay Prismic, trường mô tả ảnh được khai báo bắt buộc trong content model. Với WordPress, theme lấy alt text từ thư viện ảnh và Perxel hướng dẫn team nội dung điền mục này khi tải ảnh lên.\n- Viết chữ trên link theo trang đích. Thay vì \"xem thêm\", ghi rõ tên trang hay tên bài viết mà link dẫn tới.\n- Đo lại sau mỗi lần thay đổi lớn. Khi thêm một loại trang mới hay đổi theme, chạy lại PageSpeed trên trang đó trước khi đưa lên.\n\nCâu hỏi thường gặp\n\nWebsite đạt 100 điểm SEO có chắc lên top Google không?\n\nKhông chắc. Điểm này chỉ cho biết website không mắc các lỗi kỹ thuật cơ bản. Thứ hạng còn phụ thuộc vào nội dung có trả lời đúng câu hỏi người tìm kiếm hay không, website có được các trang khác nhắc đến hay không, và đối thủ trong cùng lĩnh vực mạnh đến đâu.\n\nĐiểm SEO có ảnh hưởng đến việc ChatGPT hay Gemini trích dẫn website không?\n\nCó liên quan nhưng không trực tiếp. Các công cụ AI cũng cần đọc được trang trước khi trích dẫn, nên những lỗi khiến Google không lập chỉ mục được thì AI cũng gặp phải. Phần việc riêng cho các công cụ AI được trình bày trong bài GEO (/insights/geo).\n\nWebsite WordPress đang có điểm SEO thấp thì sửa có khó không?\n\nPhần lớn trường hợp là không. Các lỗi thường gặp là thiếu meta description, ảnh không có alt text và link chỉ có biểu tượng mà không có chữ. Cấu hình lại plugin SEO và sửa vài chỗ trong theme thường đủ để đạt 100.\n\n1. Google PageSpeed Insights\n2. Chrome for Developers: Lighthouse SEO audits\n3. Google: Rich Results Test"},{"kind":"insight","locale":"vi","slug":"geo","title":"GEO: để ChatGPT và Gemini đọc đúng website","shortTitle":null,"excerpt":"GEO (Generative Engine Optimization) là phần việc giúp ChatGPT, Gemini hay Perplexity đọc đúng và nhắc đến website khi trả lời. Bài viết đi qua năm bước Perxel làm trên các website WordPress và Next.js: mở cửa cho bot AI, llms.txt, dữ liệu có cấu trúc, nguồn dữ liệu đầy đủ cho máy đọc và cách đo lượt truy cập từ AI.","categories":["SEO","Development"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"nextjs","label":"Next.js"},{"id":"claude","label":"Claude"},{"id":"chatgpt","label":"ChatGPT"},{"id":"gemini","label":"Gemini"}],"date":"2026-10-13","updated":null,"dateModified":"2026-10-13","url":"https://perxel.com/insights/geo","visibility":"public","deliveredByPerxel":true,"related":["seo-score","pagespeed"],"projects":["perxel-website","khatra"],"usedBy":[],"links":[{"caption":"Dịch vụ","title":"SEO và GEO cho website","href":"/services/seo"}],"body":"Ngày càng nhiều người hỏi ChatGPT hay Gemini thay vì gõ từ khóa lên Google, và câu trả lời họ nhận được là một đoạn văn tổng hợp từ nhiều website, kèm vài đường link nguồn. GEO (Generative Engine Optimization) là phần việc giúp website của bạn nằm trong số những nguồn đó: các công cụ AI đọc được trang, hiểu đúng nội dung và nhắc đến nó khi trả lời. Bài viết này đi qua năm bước Perxel làm trên các website WordPress và Next.js, cùng những gì đã có trên chính website Perxel.\n\nGEO khác SEO ở đâu\n\nPhần nền của hai việc này giống nhau. Google cho biết AI Overviews và AI Mode dùng chính các yêu cầu SEO cơ bản: trang được lập chỉ mục, nội dung hữu ích, cấu trúc rõ ràng. Một website chưa đạt các yêu cầu SEO kỹ thuật (xem bài Điểm SEO trên PageSpeed (/insights/seo-score)) thì cũng khó được các công cụ AI đọc đúng.\n\nKhác biệt nằm ở người đọc. Google xếp hạng cả trang, còn công cụ AI lấy từng đoạn để ghép vào câu trả lời. Vì vậy GEO quan tâm thêm đến việc bot AI có vào được website hay không, và mỗi đoạn nội dung có tự đứng được khi bị tách ra khỏi trang hay không.\n\nBước 1: kiểm tra bot AI có vào được website không\n\nMỗi công cụ AI có bot riêng để đọc website: GPTBot và OAI-SearchBot của OpenAI, ClaudeBot của Anthropic, PerplexityBot của Perplexity. Một website có thể chặn các bot này mà chủ doanh nghiệp không hề biết, vì việc chặn có thể đến từ ba nơi:\n\n- File robots.txt. Một số theme, plugin hay mẫu cấu hình có sẵn dòng chặn bot AI.\n- Cloudflare. Từ giữa năm 2025, Cloudflare chặn bot AI theo mặc định với các domain mới thêm vào. Nếu muốn website được AI trích dẫn, cần tắt tùy chọn này trong phần cài đặt bot của Cloudflare.\n- Hosting và tường lửa. Nhiều gói hosting giới hạn số lượt truy cập từ bot, nên bot AI có thể nhận lỗi 429 (quá nhiều yêu cầu) thay vì nội dung trang.\n\nPerxel kiểm tra cả ba nơi trên từng website, rồi xem log của máy chủ để chắc chắn các bot thật sự nhận được nội dung. Với website Perxel, robots.txt không chặn bot nào và Cloudflare để các bot AI truy cập bình thường.\n\nBước 2: llms.txt, bản tóm tắt website cho AI\n\nllms.txt là một file Markdown đặt ở địa chỉ /llms.txt, liệt kê các trang chính của website kèm một dòng mô tả cho mỗi trang. Đây là một đề xuất mở, chưa phải tiêu chuẩn chính thức, nhưng file này giúp các công cụ AI nắm được website gồm những gì mà không phải đọc từng trang.\n\n- Website WordPress. Yoast SEO tạo file llms.txt tự động từ các trang và bài viết. Sundmd, một website WordPress Perxel lập trình, dùng cách này.\n- Website Next.js. File được sinh ra từ cùng nguồn dữ liệu với nội dung trang, nên luôn cập nhật theo CMS. Trên website Perxel, llms.txt liệt kê mọi trang, dịch vụ, dự án và bài viết. Với Foldables (/products/foldables), file còn ghi rõ thông số và giá điện thoại chỉ là số liệu tham khảo, để công cụ AI không trích dẫn như số liệu chính thức.\n\nBước 3: dữ liệu có cấu trúc\n\nDữ liệu có cấu trúc (JSON-LD) mô tả nội dung trang theo một bộ từ vựng chung, Schema.org: đây là một doanh nghiệp có địa chỉ này, đây là một bài viết của tác giả này, ngày đăng này. Google dùng nó để hiển thị kết quả tìm kiếm chi tiết hơn, và các công cụ AI đọc được thông tin này mà không phải đoán từ giao diện.\n\n- Khatra Tile (/works/khatra) dùng Rank Math để khai báo địa chỉ và tọa độ của doanh nghiệp, kèm thẻ hreflang cho hai phiên bản tiếng Việt và tiếng Anh.\n- Sundmd dùng Yoast SEO để khai báo thông tin tổ chức và breadcrumb của từng trang.\n- Website Perxel khai báo thông tin studio, dịch vụ và người phụ trách ngay trong code, và mỗi bài viết có thêm tác giả cùng ngày cập nhật.\n\nSau khi khai báo, kiểm tra lại bằng Rich Results Test, vì điểm SEO trên PageSpeed không chấm phần này.\n\nBước 4: một nguồn dữ liệu đầy đủ cho máy đọc\n\nllms.txt và JSON-LD chỉ là bản tóm tắt. Với website Next.js, Perxel có thể đi xa hơn: đưa toàn bộ nội dung ra một nguồn dữ liệu riêng cho máy đọc. Website Perxel có hai nguồn như vậy:\n\n- /content.json: mọi trang, dịch vụ, dự án, sản phẩm và bài viết ở cả hai ngôn ngữ, kèm nội dung đầy đủ và bảng giá. File được tạo lại mỗi lần website cập nhật.\n- Một MCP server: cho phép các ứng dụng AI như Claude tìm kiếm và đọc nội dung website trực tiếp, thay vì phải tải từng trang về.\n\nCùng nguồn dữ liệu này cũng là nơi Ask Perxel, trợ lý trên website, tìm câu trả lời cho khách truy cập. Nhờ vậy, những gì khách hỏi trên website và những gì công cụ AI đọc được đều lấy từ cùng một nội dung.\n\nBước 5: viết từng đoạn để AI trích được\n\nVì công cụ AI lấy từng đoạn chứ không lấy cả trang, mỗi đoạn nên tự trả lời được một câu hỏi:\n\n- Trả lời ngay ở đoạn đầu. Câu hỏi chính của trang được trả lời trong hai, ba câu đầu tiên, phần giải thích chi tiết để phía sau.\n- Tiêu đề nói rõ nội dung bên dưới. Một tiêu đề như \"Chi phí hosting một website Next.js\" dễ được lấy làm nguồn hơn \"Chi phí\".\n- Số liệu kèm ngày và nguồn. Một con số có ghi ngày đo và cách đo đáng tin hơn một con số đứng một mình, với người đọc lẫn với công cụ AI.\n- Phần câu hỏi thường gặp. Mỗi câu hỏi kèm câu trả lời ngắn là một đoạn sẵn sàng để trích dẫn.\n\nĐo lượt truy cập từ AI\n\nGEO còn mới, và các công cụ AI không công bố cách họ chọn nguồn để trích dẫn. Cách đo đáng tin nhất hiện nay là đếm lượt truy cập thật: khi người dùng bấm vào link nguồn trong câu trả lời, lượt truy cập đến từ chatgpt.com, perplexity.ai hay gemini.google.com. Perxel tạo một nhóm kênh riêng cho các nguồn này trong Google Analytics, để doanh nghiệp thấy GEO mang lại bao nhiêu khách và khách đó vào trang nào.\n\nCâu hỏi thường gặp\n\nCó cần chặn bot AI để bảo vệ nội dung không?\n\nTùy mục tiêu của website. Nếu nội dung là sản phẩm bạn bán (bài báo trả phí, khóa học), chặn bot AI là hợp lý. Nếu website dùng để giới thiệu doanh nghiệp và tìm khách hàng, để bot AI đọc được sẽ giúp doanh nghiệp xuất hiện trong câu trả lời của ChatGPT hay Gemini. Theo tài liệu của OpenAI, có thể chặn bot dùng dữ liệu để huấn luyện (GPTBot) nhưng vẫn cho bot tìm kiếm (OAI-SearchBot) truy cập.\n\nWebsite WordPress có làm GEO được không?\n\nĐược. Rank Math và Yoast SEO đã hỗ trợ dữ liệu có cấu trúc, Yoast còn tạo được llms.txt tự động. Phần còn lại là kiểm tra hosting không chặn bot AI và viết lại nội dung theo cách ở bước 5.\n\nBao lâu thì website được AI nhắc đến?\n\nKhông có mốc cố định. Công cụ AI dùng tính năng tìm kiếm có thể đọc trang mới trong vài ngày đến vài tuần, giống Google. Phần kiến thức có sẵn trong mô hình chỉ cập nhật khi nhà phát triển huấn luyện phiên bản mới, nên không thể chủ động tác động vào.\n\n1. Google Search Central: AI features and your website\n2. Cloudflare: Content Independence Day\n3. llms.txt\n4. Schema.org\n5. Google: Rich Results Test\n6. OpenAI: Overview of OpenAI crawlers"},{"kind":"insight","locale":"vi","slug":"brevo-newsletter","title":"Newsletter tự động với Brevo","shortTitle":null,"excerpt":"Website đăng bài mới, sáng hôm sau người đăng ký nhận email giới thiệu bài đó mà không ai phải soạn hay bấm gửi. Cách làm newsletter tự động với gói miễn phí của Brevo, phù hợp với agency marketing và designer, developer độc lập.","categories":["Development"],"tech":[{"id":"brevo","label":"Brevo"},{"id":"cloudflare","label":"Cloudflare"},{"id":"nextjs","label":"Next.js"}],"date":"2026-10-11","updated":null,"dateModified":"2026-10-11","url":"https://perxel.com/insights/brevo-newsletter","visibility":"public","deliveredByPerxel":true,"related":[],"projects":["perxel-website"],"usedBy":[],"links":[],"body":"Newsletter là cách đơn giản để người đọc quay lại website: họ để lại email một lần, sau đó mỗi khi có nội dung mới, email sẽ tự tìm đến họ. Vấn đề là ai đó phải soạn và gửi từng email, và việc này thường bị bỏ dở sau vài tuần.\n\nBrevo là một nền tảng email marketing có gói miễn phí, và có thể làm phần việc này thay bạn. Khi website đăng bài mới, sáng hôm sau người đăng ký nhận được email giới thiệu bài đó. Không ai phải soạn email hay bấm gửi.\n\nPhần đầu bài dành cho agency và người quản lý nội dung: newsletter hoạt động thế nào, tốn bao nhiêu và team cần làm gì sau khi cài đặt. Phần chi tiết kỹ thuật nằm ở cuối bài.\n\nNewsletter hoạt động thế nào\n\n- Người đọc đăng ký bằng form ở cuối trang. Họ nhập email, đánh dấu đồng ý với chính sách bảo mật và bấm đăng ký. Brevo gửi một email xác nhận, và chỉ khi người đọc bấm vào liên kết trong đó thì địa chỉ mới được thêm vào danh sách. Cách này gọi là double opt-in, giúp danh sách không có email nhập sai hay email bị người khác đăng ký hộ.\n- Bài mới được gửi đi vào sáng hôm sau. Mỗi ngày vào giờ bạn chọn, Brevo đọc danh sách bài viết của website. Nếu có bài mới kể từ lần đọc trước, Brevo tạo email với ảnh, tiêu đề, đoạn tóm tắt và nút đọc tiếp của từng bài, rồi gửi cho cả danh sách.\n- Ngày không có bài mới thì không có email. Người đăng ký chỉ nhận email khi website thật sự có nội dung mới.\n- Website nhiều ngôn ngữ có thể tách danh sách theo ngôn ngữ. Người đăng ký ở trang tiếng Việt chỉ nhận bài tiếng Việt, người đăng ký ở trang tiếng Anh chỉ nhận bài tiếng Anh.\n- Lịch gửi có thể đổi. Thay vì gửi mỗi ngày, Brevo có thể gom bài mới thành một email mỗi tuần hoặc mỗi tháng. Cách này phù hợp với website đăng nhiều bài hoặc khi khách hàng không muốn gửi email quá dày.\n\nĐây là form đăng ký thật của Perxel, được làm theo cách trong bài. Bạn có thể đăng ký ngay tại đây.\n\nPhù hợp với ai\n\nAgency marketing quản lý website cho khách hàng. Content team vẫn đăng bài như thường lệ, newsletter tự chạy theo. Agency không cần thêm người soạn email cho từng bài, và khách hàng có thêm một kênh đưa người đọc quay lại website. Tài khoản Brevo và danh sách người đăng ký thuộc về khách hàng.\n\nDesigner và developer độc lập có blog hoặc portfolio. Ở quy mô vài trăm người đăng ký, gói miễn phí của Brevo là đủ, nên bạn có newsletter mà không phải trả phí hằng tháng.\n\nChi phí và giới hạn của gói miễn phí\n\nVới phần lớn website nhỏ, gói miễn phí của Brevo là đủ. Đây là những giới hạn cần biết trước khi chọn:\n\n- Tối đa 300 email mỗi ngày, tính chung cho mọi danh sách. Với lịch gửi mỗi ngày, mỗi người đăng ký nhận một email, nên gói miễn phí đủ cho khoảng 300 người đăng ký. Với lịch gửi mỗi tuần, giới hạn theo ngày vẫn như vậy vì cả danh sách nhận email trong cùng một ngày.\n- Email có dòng \"Sent with Brevo\" ở cuối, và gói miễn phí không cho gỡ dòng này.\n- Tính năng gửi email theo bài mới (RSS campaign) có trong gói miễn phí. Nhiều dịch vụ newsletter khác chỉ có tính năng này ở gói trả phí.\n\nKhi danh sách vượt quá giới hạn này, gói trả phí của Brevo tính theo số email gửi mỗi tháng. Giá và giới hạn có thể thay đổi, nên bạn xem trực tiếp trên trang giá của Brevo trước khi chọn.\n\nTrang giá của Brevo ngày 11/10/2026, giá hiển thị theo năm.\n\nSau khi cài đặt, team chỉ cần quản lý danh sách\n\nPhần cài đặt gồm form đăng ký, nguồn dữ liệu bài viết cho Brevo đọc, mẫu email theo nhận diện thương hiệu và lịch gửi. Sau khi các phần này chạy ổn, việc hằng ngày nằm hoàn toàn trong Brevo:\n\n- Xem danh sách người đăng ký, xuất ra file hoặc xóa một người khỏi danh sách.\n- Xem số người mở email và bấm vào bài viết sau mỗi lần gửi.\n- Đổi lịch gửi hoặc tạm dừng newsletter khi cần.\n\nTrang quản lý danh sách người đăng ký trong Brevo.\n\nNgười đăng ký tự hủy bằng liên kết ở cuối mỗi email, nên team không phải xử lý yêu cầu hủy bằng tay.\n\nQuy trình cài đặt thực ra khá đơn giản. Nếu website của bạn hoặc của khách hàng cần newsletter như vậy, Perxel có thể cài đặt và bàn giao lại tài khoản để team của bạn tự quản lý danh sách. Bạn có thể liên hệ Perxel (/contact) để trao đổi.\n\nChi tiết kỹ thuật\n\nPhần này dành cho developer muốn tự cài đặt. Cách làm áp dụng được cho mọi website có RSS feed, dù là WordPress, Next.js hay một nền tảng khác.\n\nRSS feed là nguồn dữ liệu\n\nBrevo không đọc website trực tiếp mà đọc RSS feed, một file XML liệt kê các bài viết theo thứ tự mới nhất. Mỗi bài trong feed cần có tiêu đề, đoạn tóm tắt, ảnh chia sẻ và ngày đăng. Nếu website có nhiều ngôn ngữ, hãy làm một feed cho mỗi ngôn ngữ (ví dụ /feed.xml và /en/feed.xml). WordPress có sẵn RSS feed, nên với website WordPress thì bước này gần như không phải làm gì.\n\nTrong Brevo, mỗi feed được nối với một danh sách người đăng ký và một mẫu email qua tính năng RSS campaign. Tính năng này là một integration trong mục Integrations của Brevo, không có trong API, nên phải cài đặt trong dashboard.\n\nCài đặt một RSS campaign: feed, mẫu email, danh sách người nhận và lịch gửi.\n\nTự làm form đăng ký thay vì nhúng script của Brevo\n\nBrevo có sẵn form nhúng, nhưng form nhúng tải thêm script của Brevo vào mọi trang. Cách nhẹ hơn là tự làm form: form gửi dữ liệu về server của website, server gọi API double opt-in của Brevo (POST /v3/contacts/doubleOptinConfirmation) với danh sách phù hợp. Trang tải không thêm byte nào từ Brevo. Nếu muốn, server có thể gửi thêm thông báo vào Slack hay Discord mỗi khi có người đăng ký.\n\nHãy lưu API key của Brevo dưới dạng biến môi trường bí mật trên server, không đưa vào code.\n\nBrevo chọn bài theo ngày đăng\n\nMỗi lần chạy, Brevo lấy những bài có ngày đăng (pubDate trong feed) nằm giữa lần chạy trước và lần chạy này. Với lịch 6:30 sáng, Brevo lấy các bài từ 6:00 sáng hôm trước đến 6:00 sáng hôm đó. Nếu feed lấy ngày đăng từ ngày ghi trong bài viết (ví dụ trường date trong frontmatter) thì:\n\n- Bài được đẩy lên production trong ngày ghi ở date sẽ được gửi vào 6:30 sáng hôm sau.\n- Bài có date sớm hơn ngày đăng thật sẽ không bao giờ được gửi, vì khoảng thời gian đó Brevo đã đọc qua rồi.\n- Sửa nội dung một bài cũ không gửi lại email.\n\nVì vậy, nên chọn giờ chạy sớm hơn giờ bạn thường đăng bài. Với lịch 8:30 mặc định của Brevo, khoảng thời gian kết thúc lúc 8:00, nên một bài đẩy lên sau 8:00 trong ngày ghi ở date sẽ bị bỏ qua.\n\nNhững lỗi dễ gặp khi cài đặt\n\n- Danh sách trống làm lần gửi bị lỗi. Nếu danh sách chưa có ai xác nhận đăng ký, Brevo không tạo email mà gửi về một email báo lỗi 400 (\"no contacts associated with the given recipients\"). Email báo lỗi này không tắt được. Cách xử lý là thêm email của chính bạn vào mọi danh sách, vừa để danh sách không bao giờ trống, vừa để bạn nhận một bản của mỗi email gửi đi.\n- Giới hạn IP chặn mọi lệnh gọi API. Brevo có tùy chọn chỉ cho phép API key được dùng từ một số địa chỉ IP. Các nền tảng serverless như Cloudflare Workers gọi API từ nhiều IP khác nhau, nên khi tùy chọn này bật, mọi lệnh gọi đều bị từ chối với lỗi \"unrecognised IP address\". Khi dùng các nền tảng này, cần tắt tùy chọn đó cho API key.\n- Email gửi từ địa chỉ Gmail bị từ chối. Brevo cần gửi từ một tên miền đã xác thực (SPF, DKIM, DMARC). Hãy xác thực tên miền của website và gửi từ một địa chỉ trên tên miền đó, ví dụ hello@tenmien.com.\n\nMẫu email nằm trong code\n\nMẫu email có thể viết bằng HTML trong repo của website rồi đẩy lên Brevo qua API, thay vì chỉnh trong trình soạn thảo kéo thả của Brevo. Mỗi bài là một thẻ gồm ảnh chia sẻ, tiêu đề, đoạn tóm tắt và nút đọc tiếp, cuối email là lý do người nhận nhận được email và liên kết hủy đăng ký. Khi cần đổi giao diện, chỉ cần sửa file rồi đẩy lại, nên mẫu email luôn khớp với code.\n\nNgoài phần kỹ thuật, chính sách bảo mật của website cũng cần một mục về newsletter: dữ liệu nào được lưu, ai gửi email, việc theo dõi mở và bấm email, và cách hủy đăng ký.\n\n1. Brevo: Pricing\n2. Brevo Help Center: RSS campaign integration"},{"kind":"insight","locale":"vi","slug":"nextjs-performance","title":"Tối ưu tốc độ website Next.js","shortTitle":null,"excerpt":"Những gì Perxel đã làm để website Next.js nhiều animation của mình tải nhanh, chia theo nhóm: cách đo, giao diện, code, tài nguyên, script bên thứ ba và máy chủ Cloudflare Workers. Mỗi mục có số đo trước và sau, kèm điều kiện đo.","categories":["Performance","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"react","label":"React"},{"id":"cloudflare","label":"Cloudflare"},{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"gsap","label":"GSAP"},{"id":"vercel","label":"Vercel"}],"date":"2026-10-10","updated":null,"dateModified":"2026-10-10","url":"https://perxel.com/insights/nextjs-performance","visibility":"public","deliveredByPerxel":true,"related":[],"projects":["perxel-website"],"usedBy":[],"links":[],"body":"Next.js có sẵn nhiều thứ giúp website tải nhanh: prerender trang tĩnh, tách JavaScript theo route, tối ưu ảnh và font. Tuy vậy, một website nhiều animation vẫn có thể chậm nếu không để ý từng phần, và khi chạy trên Cloudflare Workers thay vì Vercel thì có thêm những việc Next.js không tự làm.\n\nBài viết này tổng hợp những gì Perxel đã làm để tăng tốc website của chính mình (/works/perxel-website), chia theo nhóm: cách đo, giao diện, code, tài nguyên, script bên thứ ba và máy chủ. Mỗi mục có số đo trước và sau, kèm điều kiện đo. Website dùng Next.js 16, React 19, GSAP và nhiều canvas, chạy trên Cloudflare Workers qua OpenNext. Phần lớn các bước áp dụng được cho mọi dự án Next.js. Riêng phần máy chủ dành cho trường hợp chạy trên Cloudflare.\n\nĐo trước khi sửa\n\nĐiểm PageSpeed thay đổi theo từng lần đo, nên một con số đơn lẻ không đủ để biết một thay đổi có hiệu quả hay không. Hai lần đo dưới đây chạy trên cùng một phiên bản code của trang chủ, cách nhau hơn 13 tiếng: lần đầu được 68 điểm, lần sau được 95.\n\nCùng code, hai lần đo PageSpeed bản mobile: 68 điểm lúc 20:12 ngày 9/10/2026 và 95 điểm lúc 9:36 ngày 10/10/2026.\n\nVì vậy Perxel đo theo vài nguyên tắc:\n\n- Chạy Lighthouse trên máy mình, cùng phiên bản với PageSpeed. PageSpeed Insights hiện dùng Lighthouse 13.5 với throttling giả lập. Chạy cùng phiên bản trên máy mình cho kết quả gần với PageSpeed và không bị giới hạn số lần gọi API.\n- Lấy trung vị của nhiều lần đo. Ngày 10/10/2026, ba lần đo bản mobile trên production cho 86, 91 và 93 điểm, hai lần đo bản desktop cho 96 điểm. Khi so sánh hai phiên bản, Perxel chạy xen kẽ từng cặp để máy đo chịu cùng điều kiện.\n- Kiểm tra lại LCP bằng throttling thật khi con số đáng ngờ. Chế độ giả lập cộng thời gian tải của mọi request bắt đầu trước LCP vào chính LCP. Có lần chế độ giả lập báo LCP 4,6 giây trong khi throttling thật (--throttling-method=devtools) đo được 1,8 giây.\n- Xem cấu hình máy đo trước khi nghi ngờ code. Có lần PageSpeed cho 47 và 58 điểm, trong khi Lighthouse cùng phiên bản trên máy Perxel cho 83 đến 98 điểm với cùng trang. TBT cao gấp 5 đến 10 lần thường là dấu hiệu máy đo đang chậm hoặc bận. Thông số này nằm ở mục \"CPU/Memory Power\" cuối báo cáo.\n- Xem layout-shifts trước khi xem điểm CLS. Một lần xê dịch có thể chiếm toàn bộ điểm CLS. Lighthouse với --save-assets giữ lại trace, trong đó có vị trí của từng phần tử bị xê dịch.\n- Muốn biết chuyện gì xảy ra lúc tải trang thì gắn script theo dõi vào trang. Perxel điều khiển Chrome headless qua DevTools Protocol, gắn một script chạy trước mọi thứ để ghi lại animationstart, thay đổi DOM và các lần startViewTransition. Lỗi view transition ở phần Code bên dưới được tìm ra theo cách này, vì điểm số và CLS đều không cho thấy nó.\n\nĐiểm lab và dữ liệu người dùng thật (CrUX) khác nhau thế nào được giải thích trong bài PageSpeed Insights & Core Web Vitals (/insights/pagespeed).\n\nGiao diện: thứ người xem thấy đầu tiên phải hiện sớm\n\nPhần tử LCP không chờ JavaScript\n\nTiêu đề lớn ở trang chủ là phần tử LCP. Bản đầu tiên cho tiêu đề xuất hiện bằng GSAP, nên tiêu đề phải chờ JavaScript tải và chạy xong mới hiện: LCP bản mobile lên tới 8,7 giây. Bây giờ phần co giãn chữ theo khung dùng CSS (đơn vị cqw trên chiều rộng dòng tính bằng em), animation xuất hiện là CSS keyframes, và một đoạn script inline nhỏ chỉ hiện khối chữ khi font tiêu đề đã tải xong (chờ tối đa 1,2 giây). LCP giảm còn khoảng 1,8 giây và bằng FCP.\n\nCó hai chi tiết dễ vấp. Thứ nhất, các chữ bắt đầu ở opacity 1% thay vì 0, vì Chrome không tính một phần tử có opacity 0 lúc hiện lần đầu là ứng viên LCP. Thứ hai, đoạn script inline nằm cuối khối chữ: trình duyệt có thể vẽ trang trong lúc chờ script, nên mọi thứ đặt sau nó sẽ hiện muộn và làm tiêu đề ở giữa màn hình bị xê dịch.\n\nTiêu đề hiện ngay khi tải trang, nhân vật Lottie vào sau.\n\nTrạng thái ban đầu nằm sẵn trong CSS\n\nHTML từ server được vẽ lên trước khi React hydrate. Vì vậy, nếu một useLayoutEffect thay đổi layout sau đó, người xem vẫn thấy trang bị xê dịch. Ở trang chủ Perxel, phần hero kéo dải màu xanh bên dưới lên một màn hình bằng margin-top để làm hiệu ứng nước dâng. Lúc đầu thao tác này chạy bằng JavaScript, nên CLS bản mobile trên production là 0,9 và desktop là 0,64. Sau khi đưa giá trị mặc định vào CSS (JavaScript chỉ ghi đè sau đó), CLS về 0.\n\nQuy tắc rút ra: phần layout do JavaScript thay đổi cần có sẵn trạng thái ban đầu trong CSS. Khi đổi kích thước của phần đó, phải đổi cả trong CSS.\n\nĐơn giản hóa giao diện trên điện thoại\n\nTrên điện thoại, Perxel giữ nguyên nội dung nhưng thay vài hiệu ứng nặng bằng phiên bản nhẹ hơn:\n\n- Nhân vật ở hero có ảnh poster là SVG inline. Animation Lottie cần tải 486 KB WASM, nên trên màn hình dưới 768px, chỗ của nhân vật hiện sẵn frame đầu tiên dưới dạng SVG (22 KB, 9,6 KB khi gzip) rồi chuyển sang Lottie khi đã sẵn sàng. Bản đầu dùng ảnh WebP thì ảnh này trở thành phần tử LCP thay cho tiêu đề. SVG inline thì không được tính là ứng viên LCP.\n- Mép nước trên màn hình cảm ứng là CSS, không phải canvas. Trên desktop, mép nước là canvas phản ứng với con trỏ. Trên điện thoại không có con trỏ nên Perxel thay bằng một mask hình sóng trượt ngang bằng transform, không có script chạy mỗi frame.\n- Dải logo công nghệ có chế độ nhẹ trên điện thoại. Canvas mép nước vẽ ở mật độ điểm ảnh 1x, các viên logo dùng viền phẳng 1px thay cho bóng đổ mờ 18px, và phần mô phỏng vật lý chạy cách một frame.\n- Màn hình dọc nhận danh sách dự án thường. Hàng card uốn theo sóng bằng canvas chỉ chạy trên màn hình ngang cao từ 600px. Điện thoại và tablet dựng đứng nhận danh sách dọc.\n- Pin màn hình dùng position: sticky thay cho pin: true của GSAP. Pin của GSAP chuyển phần tử sang position: fixed và di chuyển nó bằng JavaScript, nên trên Safari iOS phần này trễ hơn thao tác cuộn và bị giật. Với sticky, trình duyệt tự giữ phần tử, ScrollTrigger chỉ còn điều khiển animation theo vị trí cuộn.\n\nPhần nặng ở phía dưới khởi tạo muộn\n\nCác section dùng canvas ở cuối trang vẫn dựng pin và layout ngay lúc đầu, vì layout không được thay đổi về sau. Riêng phần vẽ và tải dữ liệu được hoãn lại. Hàng card dự án chỉ tải ảnh và video khi người dùng cuộn tới gần (trong khoảng 2 lần chiều cao màn hình). Phần chữ rót nước và con cá voi (font, bố cục chữ, WebGL) khởi tạo 1,5 giây sau khi trang tải xong, hoặc sớm hơn nếu người dùng cuộn, chạm hay bấm phím. Trước đó, video 1,2 MB của một dự án được tải ngay khi mở trang dù nằm cách màn hình đầu vài lần cuộn.\n\nTrang chủ bản mobile. LCP đo bằng Lighthouse với throttling thật, CLS trên PageSpeed production, dữ liệu tải lúc mở trang đo bằng Chrome headless với CPU chậm 4 lần (tháng 10/2026).\n\nCode: mỗi trang chỉ tải JavaScript nó cần\n\nServer component vẫn có thể kéo client component vào trang\n\nNext.js đưa vào script của một trang mọi client component nằm trong cây module của server component, kể cả component không được render. Footer của website Perxel đọc danh sách bài viết trên mọi trang, và danh sách này lấy frontmatter bằng cách import file MDX. Vì vậy mọi client component mà một bài viết nào đó dùng (dialog, accordion, lightbox, Lottie player) đều có mặt trong JavaScript của mọi trang, chiếm 5 đến 18% JavaScript mỗi trang.\n\nCách sửa là đọc frontmatter từ JSON thay vì từ MDX. Một script chạy trước next dev và next build ghi frontmatter của mọi bài vào content/meta.generated.json, và chỉ route chi tiết của từng bài mới import file MDX. Đây là thay đổi giảm JavaScript nhiều nhất. Để kiểm tra một trang có đang tải code nó không dùng hay không, tìm tên class của component trong các chunk mà HTML của trang đó liệt kê.\n\nImport sau một flag false vẫn bị đóng gói\n\nMenu toàn màn hình cũ của Perxel đã được tắt bằng một flag false, nhưng Header vẫn import nó. Bundler không bỏ import này, nên con trỏ hoạt hình và mọi trạng thái của nó vẫn có mặt trên mọi trang, trên mọi thiết bị. Tương tự, chỉ một dòng import của section cũ (không còn render) cũng đủ đưa thư viện motion vào trang chủ. Component đã tắt nên được import bằng next/dynamic, hoặc bỏ import hẳn.\n\nCode của một loại thiết bị chỉ tải trên thiết bị đó\n\nThanh điều hướng dưới đáy màn hình chỉ dùng trên màn hình dưới 1024px, con trỏ hoạt hình chỉ dùng với chuột, và Lenis (cuộn mượt) chỉ cần với con lăn chuột. Mỗi phần là một chunk riêng, tải sau khi hydrate và chỉ trên thiết bị cần nó: next/dynamic với ssr: false đặt sau useMediaQuery, hoặc import() trong một effect. Riêng thanh điều hướng giúp desktop bớt 33 KB brotli.\n\nSau mỗi lần build, nên kiểm tra mọi đường dẫn /_next/static trong HTML đều tồn tại. Có lần Turbopack sinh ra thẻ preload cho một chunk không có thật, gây lỗi 404 trên các trang bài viết.\n\nLink luôn hiện trên màn hình không prefetch theo viewport\n\nMặc định, của Next.js prefetch route khi link xuất hiện trong viewport. Header và footer link tới mọi trang, nên trang chủ tải luôn JavaScript của các trang khác ngay sau khi mở. Perxel viết một component link riêng chỉ prefetch khi người dùng đưa chuột, focus hoặc chạm vào link. Lighthouse báo \"unused JavaScript\" giảm từ 110 KiB xuống 22 KiB. Các nút ở màn hình đầu tiên cũng dùng component này, vì một prefetch lúc tải trang có thể phải chờ server khởi động (xem phần Máy chủ).\n\nView transition chỉ bật sau thao tác đầu tiên\n\nVới giá trị mặc định auto, của React chạy một hiệu ứng chuyển cảnh cho mỗi lần cập nhật sau hydrate. Trên production có ba lần như vậy trong 1,5 giây đầu, mỗi lần là một ảnh chụp trang mờ dần trong 300 ms đè lên trang thật, nên header và hero trông như được vẽ hai lần. CLS vẫn là 0, nên lỗi này chỉ thấy được khi ghi lại các lần gọi startViewTransition. Bây giờ view transition chỉ bật sau thao tác đầu tiên của người dùng. Chuyển trang luôn đến sau một thao tác, nên hiệu ứng chuyển trang vẫn chạy bình thường.\n\nJavaScript mỗi trang tải (brotli, ngày 9/10/2026) và mục \"unused JavaScript\" của Lighthouse trên trang chủ. Sau đó, trên điện thoại, trang chủ giảm thêm 27 KB và các trang khác giảm thêm 18 đến 19 KB nhờ tách code theo thiết bị.\n\nTài nguyên: font, ảnh và video\n\n- Tự host font và chỉ giữ những ký tự cần dùng. Với next/font/google, một trang tiếng Việt tải thêm cả bộ latin-ext, vì các chữ ă, đ, ơ, ư nằm trong dải ký tự của bộ này: tổng cộng 7 file font, 218 KB trước LCP. Bây giờ Inter và Manrope mỗi font chỉ còn một file, cắt bằng pyftsubset theo dải latin và tiếng Việt: Inter 53 KB, Manrope 29 KB.\n- Font nào có trong DOM cũng được tải lúc mở trang, kể cả khi nằm ở cuối trang. Font Geist chỉ dùng cho vài con số trong danh sách dịch vụ, nhưng vẫn là 29 KB tải ngay lúc đầu và làm FCP lúc 1,21 giây, lúc 1,66 giây tùy request font bắt đầu trước hay sau lần vẽ đầu tiên. Các con số chuyển sang Inter với tabular-nums và Geist được bỏ khỏi dự án.\n- Ảnh có kích thước gần với khung hiển thị. Logo giới hạn ở 128px, logo trong badge công nghệ (hiện ở 24px) có bản 48px riêng (cả bộ từ 76 KB còn 25 KB), thumbnail dự án tối đa 1100px, và thuộc tính sizes sát với chiều rộng thật của khung.\n- Poster của video là có kích thước, không dùng thuộc tính poster. Thuộc tính poster không có srcset, nên điện thoại phải tải ảnh 1100px cho một khung 365px.\n- Video nén lại theo kích thước hiển thị. Các video dự án được encode lại ở 1120px, crf 34, không có âm thanh, bật faststart: tổng dung lượng từ 20,5 MB còn 6,5 MB. Bản video ẩn chỉ dùng để giữ layout có preload=\"none\" để không tải thêm lần nữa.\n\nDung lượng font tải trước LCP trên một trang tiếng Việt, tổng dung lượng video dự án và bộ logo trong badge công nghệ (tháng 10/2026).\n\nScript bên thứ ba\n\nGoogle Analytics và Cloudflare Web Analytics chỉ tải khi người dùng có thao tác đầu tiên (cuộn, di chuột, chạm, bấm phím, click), hoặc sau 15 giây nếu không có thao tác nào. Lúc đầu thời gian chờ là 8 giây, đủ để lần đo của PageSpeed chạy tới và tải gtag (172 KiB, trong đó 70 KiB bị báo là không dùng).\n\nPerxel ghi rõ điều này vì nó cho thấy giới hạn của điểm lab: lần đo giả lập không cuộn hay chạm vào trang và kết thúc trước 15 giây, nên không bao giờ tính phần script này. Người xem thật vẫn tải nó ngay khi cuộn trang, sau khi trang đã hiện. Cái giá phải trả là người xem rời trang trong 15 giây đầu mà không thao tác gì sẽ không được ghi nhận. Script của Cloudflare Web Analytics được cài thủ công thay vì để Cloudflare tự chèn, vì cách tự chèn tải script ngay lúc mở trang.\n\nMáy chủ: Cloudflare Workers không tự làm những gì Vercel làm sẵn\n\nTrên Vercel, trang đã prerender được trả về từ edge cache mà không cần khởi động ứng dụng. Trên Cloudflare, OpenNext đóng gói cả ứng dụng Next.js thành một Worker (của Perxel là 17,5 MB), và mọi request đi qua Worker này, kể cả request lấy một trang HTML đã prerender sẵn.\n\nWorker phải khởi động ở request đầu tiên\n\nVới một website ít truy cập, Worker thường chưa chạy sẵn ở vị trí gần người xem. Trong một lần đo Lighthouse trên production, HTML mất 2,84 giây mới bắt đầu trả về, và mọi request khác phải chờ nó. Trên cùng một kết nối, request HTML đầu tiên chờ 0,73 giây, chín request tiếp theo chỉ 0,09 đến 0,19 giây, bằng một file CSS tĩnh. PageSpeed luôn đo như một lượt truy cập đầu tiên, và người vào từ Google cũng vậy.\n\nMột Worker nhỏ đứng trước Next.js\n\nPerxel đặt một Worker khoảng 40 dòng, không có code Next.js, trước Worker của OpenNext. Khi trình duyệt tải một trang đã prerender (GET hoặc HEAD, không có header RSC hay Next-Router-, không có tham số _rsc), Worker này trả về bản HTML đã lưu sẵn trong static assets, kèm đúng các header mà OpenNext gửi. Mọi request khác (dữ liệu khi chuyển trang trong site, form, API, ảnh, OG image, trang 404, redirect) được chuyển tiếp sang Worker của OpenNext qua service binding. Cách làm này giống cách Vercel và OpenNext trên AWS xử lý trang tĩnh, nhưng OpenNext trên Cloudflare chưa có sẵn nên Perxel tự viết.\n\nĐường đi của một request: tầng static assets, Worker nhỏ đứng trước, rồi mới tới ứng dụng Next.js.\n\nThời gian chờ server trên production, đo bằng curl ngày 10/10/2026, mỗi loại 8 request trong cùng một phút. Hai loại request không hoàn toàn giống nhau: trang HTML đi qua Worker nhỏ, dữ liệu chuyển trang (RSC: 1) đi tới OpenNext.\n\nWorker nhỏ này dựa vào những chi tiết nội bộ của Next.js và OpenNext, không phải API công khai: các header mà router dùng khi lấy dữ liệu chuyển trang, cấu trúc thư mục build, và các header OpenNext gửi kèm trang. Nếu một bản nâng cấp đổi những chi tiết này, link trong site có thể hỏng mà build vẫn chạy bình thường. Vì vậy sau mỗi lần nâng cấp Next.js hoặc OpenNext, Perxel chạy cả hai Worker trên máy và kiểm tra theo danh sách: trang có được trả từ Worker nhỏ không, request RSC có đi tới OpenNext không, HTML có giống hệt bản của OpenNext không, trang 404 và redirect có đúng không. Sau mỗi lần deploy, một script tự kiểm tra lại các điểm này trên production. Nếu có lỗi, chỉ cần trỏ domain về lại Worker của OpenNext trong vài giây, vì Worker đó vẫn chạy được toàn bộ site một mình.\n\nNhững thiết lập khác trên Workers\n\n- Cache dài hạn cho /_next/static. File trong thư mục này có hash trong tên, nên có thể đặt max-age=31536000, immutable trong _headers. Mặc định là max-age=0, must-revalidate, nên mỗi lần quay lại trang, trình duyệt phải hỏi lại server cho từng chunk.\n- Bật binding IMAGES cho /_next/image. Nếu thiếu, OpenNext trả ảnh gốc không resize: Lighthouse từng báo một ảnh 1440px cho khung 634px.\n- Không có request tới OpenNext lúc tải trang. Mọi request không được prerender (/api/, dữ liệu chuyển trang) đều làm Worker của OpenNext khởi động, có lúc mất 1 đến 3 giây. Badge trạng thái ở footer từng gọi API hai lần lúc mở trang. Bây giờ nó gọi một lần, 1,5 giây sau khi trang tải xong hoặc khi người dùng có thao tác đầu tiên.\n- Không đọc file lúc chạy. Workers không có ổ đĩa, và OpenNext có thể chạy lại module của trang tĩnh khi cache trống. Một lệnh fs.readdirSync chạy được lúc next build vẫn sẽ lỗi trên production. Danh sách bài viết được liệt kê sẵn trong code.\n\nNhững cách đã thử rồi bỏ\n\n- experimental.inlineCss. FCP đo bằng throttling thật giảm từ 2,1 xuống 0,8 giây, nhưng điểm PageSpeed giảm từ 88 xuống 83 và LCP giả lập tăng khoảng 1 giây. CSS bị chèn hai lần (trong HTML và trong RSC payload), và chế độ giả lập tính phần HTML lớn hơn vào LCP.\n- Cache Rule của Cloudflare cho HTML. Khi route có Worker, Worker chạy trước và Cache Rule không có tác dụng. Nếu có tác dụng thì cũng rủi ro, vì HTML cũ trong cache sẽ trỏ tới các chunk đã bị xóa ở lần deploy sau.\n- Hoãn GSAP tới sau phần hero. GSAP chỉ chiếm 44 KB trong 601 KB tải trước LCP, trong khi phải sửa khoảng 30 module. Perxel đo trước và quyết định không làm.\n- Trả HTML từ static assets ngay trong Worker lớn. Cách này chỉ nhanh hơn khoảng 55 ms ở trung vị, vì Worker lớn vẫn phải khởi động. Lần thử này lấy trung vị của các request đã \"nóng\", nên không thấy được vấn đề khởi động. Worker nhỏ ở trên giải quyết đúng phần đó.\n\nChecklist cho dự án Next.js tiếp theo\n\n- Đo bằng Lighthouse cùng phiên bản PageSpeed, lấy trung vị, so sánh từng cặp, và kiểm tra LCP bằng throttling thật.\n- Phần tử LCP hiện bằng HTML và CSS, không chờ JavaScript.\n- Phần layout do JavaScript thay đổi có trạng thái ban đầu trong CSS.\n- Trên điện thoại, thay hiệu ứng nặng bằng phiên bản nhẹ thay vì chỉ ẩn bằng CSS.\n- Section nặng ở cuối trang chỉ tải dữ liệu khi người dùng tới gần hoặc có thao tác đầu tiên.\n- Kiểm tra client component trong cây module của mọi server component dùng chung (layout, header, footer).\n- Code của một loại thiết bị nằm trong chunk riêng, sau useMediaQuery hoặc import().\n- Link luôn hiện trên màn hình chỉ prefetch khi người dùng có ý định bấm.\n- Font tự host, cắt theo dải ký tự, và không thêm font cho vài nhãn nhỏ.\n- Script bên thứ ba tải sau thao tác đầu tiên, và ghi rõ đánh đổi.\n- Trên Cloudflare Workers: trang tĩnh không đi qua Worker lớn, /_next/static cache dài hạn, bật binding IMAGES, không dùng fs.\n\nCâu hỏi thường gặp\n\nChạy trên Vercel thì có cần Worker đứng trước không?\n\nKhông cần. Vercel trả trang đã prerender từ edge cache mà không khởi động ứng dụng, nên vấn đề khởi động ở request đầu tiên gần như không xảy ra với trang tĩnh. Các phần về giao diện, code, tài nguyên và script bên thứ ba vẫn áp dụng như nhau.\n\nCó nên chạy theo điểm PageSpeed không?\n\nPerxel không hứa điểm số cho website nào. Như hình ở đầu bài, cùng một phiên bản code có thể được 68 hoặc 95 điểm. Điểm còn phụ thuộc vào nội dung đăng lên sau này, hosting và các script bên thứ ba. Mục tiêu thực tế hơn là để phần tử LCP hiện sớm, trang không xê dịch, và mỗi trang không tải code nó không dùng. Khi website có đủ lượt truy cập, dữ liệu CrUX là con số nên xem trước. Bài PageSpeed Insights & Core Web Vitals (/insights/pagespeed) có ba trường hợp thật cho thấy điểm lab và dữ liệu người dùng thật có thể chênh nhau thế nào.\n\nBản điện thoại có bị mất hiệu ứng không?\n\nNội dung giữ nguyên trên mọi thiết bị. Những hiệu ứng cần con trỏ (mép nước gợn theo chuột, con trỏ hoạt hình) chỉ có trên desktop. Những hiệu ứng nặng (canvas mép nước, hàng card uốn cong) có phiên bản nhẹ hơn hoặc chuyển thành layout thường trên điện thoại.\n\n1. OpenNext: Cloudflare\n2. web.dev: Largest Contentful Paint\n3. Next.js: Link component, prefetch\n4. fontTools: pyftsubset\n5. Cloudflare Workers: Service bindings\n6. Cloudflare Workers: Static assets headers\n7. Google: About PageSpeed Insights"},{"kind":"insight","locale":"vi","slug":"lottie-animation","title":"Lottie animation","shortTitle":null,"excerpt":"Lottie là gì? Lottie giúp đóng gói animation thành file nhẹ và sắc nét để dùng trên website. Cùng tìm hiểu cách đổi màu theo brand, cách dùng trên WordPress, Next.js và thử vọc ngay trong bài.","categories":["Animation","Design"],"tech":[{"id":"lottie","label":"Lottie"},{"id":"wordpress","label":"WordPress"},{"id":"gutenberg","label":"Gutenberg"},{"id":"nextjs","label":"Next.js"}],"date":"2026-10-01","updated":null,"dateModified":"2026-10-01","url":"https://perxel.com/insights/lottie-animation","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Lottie là một công cụ giúp đóng gói animation thành file để chia sẻ, sử dụng trên đa nền tảng. Tương tự như cách chúng ta chia sẻ một file ảnh hoặc file video. Ở bài viết này, chúng ta sẽ tìm hiểu qua về Lottie, các ứng dụng trên website và cách sử dụng.\n\nHầu hết các ảnh minh hoạ trên website Perxel đều sử dụng artwork từ nhiều tác giả trên LottieFiles, sau đó tuỳ biến màu sắc để tương đồng với nhận diện thương hiệu của Perxel. Perxel cũng dùng Lottie cho website của khách hàng, cả WordPress lẫn Next.js.\n\nLottie là gì\n\nLottie là một định dạng animation do Airbnb phát triển. Designer làm animation trong After Effects rồi xuất ra file Lottie, hoặc chọn file có sẵn trên thư viện LottieFiles. File này mô tả hình vector và chuyển động của chúng, trình duyệt đọc file và vẽ lại animation.\n\nVì là vector nên animation render sắc nét ở mọi kích thước màn hình. Vì là file chứa dữ liệu chứ không phải điểm ảnh cố định nên sau khi xuất file vẫn đổi được màu sắc, điều khiển tốc độ và timeline, tương tự như một video, nhưng nhẹ và sắc nét hơn.\n\nVí dụ, file Lottie tên lửa trên trang chủ Perxel chỉ nặng 26 KB. Dữ liệu JSON bên trong file nặng 283 KB, định dạng .lottie đã nén lại còn chưa tới một phần mười. Khi bàn giao, designer nên gửi file .lottie thay vì .json.\n\nChọn file Lottie cho design\n\nTrước khi chọn file Lottie cho design, designer nên xem vài điều sau:\n\n- Chọn hình vector phẳng. Một số file Lottie nhúng ảnh PNG bên trong. Loại này nặng hơn, mờ khi phóng to và khó đổi màu. Trong 22 file Lottie trên website Perxel, chỉ có 1 file như vậy.\n- Màu solid dễ đổi hơn gradient. Màu solid có thể được sửa thẳng trong file. Gradient thường cần phải xem lại After Effects hoặc trình chỉnh sửa của LottieFiles.\n- Xem trước animation sẽ được đặt trên nền màu gì. Một hình đẹp trên nền trắng có thể bị chìm khi đặt trên nền màu brand. Website Perxel có một bản màu sáng riêng cho các card nền xanh.\n- Muốn animation chạy lặp lại liên tục thì frame đầu và frame cuối phải khớp nhau. Nếu không, mỗi vòng lặp sẽ có một cú giật.\n\nĐổi màu theo brand\n\nFile tải từ LottieFiles có thể do nhiều tác giả vẽ nên, do đó mỗi file sẽ có một bộ màu riêng biệt. Khi đặt cạnh nhau nhìn sẽ không đồng bộ. Perxel đổi toàn bộ màu của từng file về một bảng màu chung: dải xanh của brand, các màu trung tính ấm và tối đa một màu cam làm điểm nhấn, như lửa tên lửa hay tia sáng.\n\nBảng màu được chia theo vai trò: màu cho nét viền, màu cho mặt sáng và mặt tối của vật màu xanh, màu cho nền, màu cho điểm nhấn. Mỗi màu trong file gốc được gán vào một vai trò, rồi thay mã màu ngay trong file. Không cần mở lại After Effects, và gần 20 hình từ nhiều tác giả khác nhau trên Perxel đều thống nhất một bảng màu với nhau.\n\nNếu dự án có bảng màu riêng cho illustration, designer nên gửi kèm khi bàn giao để developer đổi màu đúng ngay từ đầu, không phải đoán.\n\nGóc vọc vạch\n\nFile Lottie có thể được điều khiển tự do như một đoạn video, điều đặc biệt là chúng ta có thể đổi màu của video này. Thử vọc các chức năng dưới đây nhé.\n\nChế độ chạy:\n\n- Chạy khi scroll: animation chạy khi xuất hiện trên màn hình và dừng lại khi scroll qua. Hợp với ảnh minh hoạ trong các section.\n- Chạy khi hover: chỉ chạy khi rê chuột vào. Hợp với card và icon. Trên mobile thì không có hành động hover, thay vào đó, Perxel chọn cách sử dụng hover trên desktop và tự động chuyển sang chạy khi scroll trên mobile.\n- Chạy một lần: chạy hết rồi dừng ở khung cuối. Hợp với những lúc như gửi form thành công.\n\nNgoài ra:\n\n- Tốc độ: có thể điều chỉnh linh hoạt.\n- Màu nền: thay đổi thoải mái tuỳ vị trí sử dụng.\n\nKhi design có animation, hãy ghi chú chế độ chạy (scroll hay hover) ngay cạnh frame trong Figma. Developer sẽ không phải đoán và tránh hiểu nhầm, và đây cũng là một phần để có Figma handoff (/insights/figma-handoff) gọn gàng.\n\nNgười xem trang web thấy gì\n\nCó thể bạn sẽ băn khoăn là thêm animation có làm web chậm không? Đây là cách Perxel sử dụng Lottie trên website:\n\n- Dùng file nhẹ để tránh tăng dung lượng tải trang. Các file Lottie trên website này nặng từ 2 KB đến khoảng 110 KB, thấp hơn một file PNG thông thường.\n- Không chạy khi nằm ngoài vùng nhìn. Animation nằm ngoài màn hình sẽ tạm dừng, máy không phải tiêu tốn tài nguyên để render những thứ mà người xem không thấy.\n- Trang không bị giật khi load (CLS). Animation được lên sẵn khung layout trước khi file tải xong, giúp nội dung bên dưới không bị đẩy xuống.\n- Tôn trọng cài đặt của người xem. Người dùng đã bật chế độ giảm chuyển động (Reduce motion) trong hệ điều hành sẽ chỉ thấy một khung hình đứng yên.\n\nNgoài ra, để render Lottie, trình duyệt cần tải thêm một thư viện khoảng 500 KB. Perxel tự host thư viện này và chỉ tải trên những trang có Lottie. Trình duyệt chỉ cần tải một lần, các trang sau sẽ dùng lại.\n\nLottie trên WordPress\n\nWebsite WordPress có thể dùng Lottie bằng cách tải plugin chính thức của LottieFiles. Plugin này sẽ thêm một block Lottie vào trình soạn thảo Gutenberg.\n\nTrong block có nhiều cách thêm animation: tìm trong thư viện LottieFiles, kéo thả file, dán link, hoặc chọn file đã lưu trong Media Library. Ở thanh bên của block, người quản trị chỉnh được tốc độ, cách chạy (khi tải trang, khi click, khi cuộn hoặc khi hover), lặp hay chạy một lần, chạy ngược, kích thước theo từng màn hình và màu nền.\n\nKhi nào không nên dùng Lottie\n\nNếu chuyển động quá dài, nội dung chuyển động không thể minh hoạ bằng vector, ví dụ như texture hoặc 3D, lúc này file Lottie không còn nhẹ nữa và sử dụng video sẽ là một lựa chọn tốt hơn.\n\nNếu chuyển động là visual chính, xuất hiện đầu tiên trong trang hoặc chiếm diện tích lớn thì nên ưu tiên sử dụng ảnh tĩnh để tối ưu về tốc độ tải. Bởi vì dù có thể nhẹ hơn một số file ảnh, Lottie luôn phải chờ JS load xong mới có thể render. Trang chủ Perxel cũng có Lottie ở màn hình đầu, nhưng chỉ là chi tiết trang trí cạnh tiêu đề.\n\nNếu chỉ là hiệu ứng đơn giản như đổi màu nút, mờ dần hay trượt vào thì CSS đã làm được, không cần thêm file Lottie.\n\nNếu dự án của bạn cần sử dụng animation để trang web không quá tĩnh và trông vui vẻ hơn, năng động hơn, hãy xem thêm dịch vụ Web animation (/services/web-animation) của Perxel.\n\n1. Lottie, Airbnb\n2. LottieFiles plugin, WordPress.org\n3. How to add Lottie animations to WordPress, LottieFiles\n4. dotlottie-web, LottieFiles"},{"kind":"insight","locale":"vi","slug":"tinacms","title":"TinaCMS & Next.js","shortTitle":null,"excerpt":"Phân tích TinaCMS, giải pháp Headless CMS Git-backed hỗ trợ Click-to-Edit trực tiếp trên giao diện Next.js, không giới hạn ngôn ngữ và tối ưu chi phí duy trì dài hạn.","categories":["CMS","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"}],"date":"2026-09-15","updated":null,"dateModified":"2026-09-15","url":"https://perxel.com/insights/tinacms","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Dịch vụ liên quan","title":"Website Next.js & Headless CMS","href":"/services/nextjs"}],"body":"Hầu hết các Headless CMS dạng SaaS quản lý dữ liệu trên cơ sở dữ liệu đám mây riêng và thu phí định kỳ theo số lượng editor, dung lượng hoặc số ngôn ngữ. TinaCMS chọn một hướng đi khác: một Headless CMS mã nguồn mở theo mô hình Git-backed, tích hợp trực tiếp vào mã nguồn của dự án Next.js.\n\nTại Perxel, TinaCMS là một trong những giải pháp cốt lõi được nghiên cứu và ứng dụng thực tế để giải bài toán về trải nghiệm biên tập trực quan và chi phí duy trì dài hạn cho doanh nghiệp. Cần nói rõ: TinaCMS trước hết là một visual editor, phần tính năng CMS xung quanh (content modeling, quản trị, rollback) chỉ ở mức cơ bản, không sâu bằng một Headless CMS thương mại như Prismic.\n\nTrải nghiệm Click-to-Edit ngay trên giao diện\n\nĐiểm khác biệt lớn nhất của TinaCMS so với đa số Headless CMS truyền thống là khả năng Visual Editing. Thay vì nhập văn bản vào một ô form trong trang quản trị riêng biệt rồi mở tab preview để xem thử, quản trị viên đăng nhập vào TinaCMS và chỉnh sửa trực tiếp trên giao diện của website.\n\nNgười dùng chỉ cần nhấp vào tiêu đề, đoạn văn hoặc hình ảnh trên trang để chỉnh sửa. Mọi thay đổi phản hồi ngay lập tức trên màn hình. Trải nghiệm này gần giống các công cụ no-code như Webflow hay Framer, nhưng vẫn giữ nguyên khả năng tối ưu hiệu năng và tùy biến mã nguồn của Next.js.\n\nChỉnh sửa trực tiếp trên giao diện thật, minh họa từ dự án Atlas Robotics.\n\nKiến trúc Git-backed: dữ liệu nằm trong mã nguồn dự án\n\nKhác với các Headless CMS lưu dữ liệu trong cơ sở dữ liệu SQL hoặc NoSQL bên thứ ba, TinaCMS hoạt động theo cơ chế Git-backed. Mỗi lần người dùng bấm Publish, hệ thống thực hiện một Git commit để lưu thay đổi dưới dạng tệp JSON hoặc Markdown ngay trong kho mã nguồn GitHub của dự án.\n\nVì dữ liệu nội dung sống cùng mã nguồn, website có thể biên dịch tĩnh (SSG) và triển khai lên hạ tầng Edge Network như Cloudflare Workers hoặc Vercel mà không cần duy trì cơ sở dữ liệu hay dịch vụ hosting media riêng. Doanh nghiệp cũng sở hữu toàn bộ lịch sử thay đổi nội dung qua Git history.\n\nMỗi trang là một tệp Markdown riêng, quản lý trực tiếp trong repository của dự án.\n\nNhững lợi thế cốt lõi\n\n- Không giới hạn ngôn ngữ. Vì dữ liệu lưu trực tiếp trong repository, TinaCMS cho phép cấu hình 3, 5 hay nhiều ngôn ngữ hơn mà không bị ràng buộc bởi chi phí nâng cấp gói theo locale.\n- Không tính phí theo băng thông. Nội dung phục vụ từ chính hạ tầng biên dịch tĩnh của website, không qua một CDN riêng của CMS tính phí theo lượt tải.\n- Chi phí duy trì tối giản. Gói miễn phí của TinaCMS hỗ trợ 2 tài khoản editor, đủ dùng cho phần lớn website doanh nghiệp vận hành bởi 1 đến 2 người phụ trách nội dung. Khi team lớn hơn, gói Team trả phí (khoảng $24/tháng) nâng lên 3 tài khoản editor.\n\nNội dung từng ngôn ngữ tách riêng theo thư mục: en, vi, zh, minh họa từ dự án Atlas Robotics.\n\nĐánh giá thực tế: 8/10 cho marketing website\n\nSau nhiều năm dùng WordPress làm CMS chính, Perxel chấm TinaCMS 8/10 cho các dự án marketing website. Kiến trúc Git-backed là điểm cộng lớn, nhưng hai điểm trừ dưới đây là giới hạn thực tế cần biết trước khi triển khai.\n\n- Khả năng mở rộng admin panel còn hạn chế (-1). Perxel từng thử xây dựng một dashboard riêng để theo dõi SEO và số liệu đa ngôn ngữ ngay trong TinaCMS, chạy tốt ở local nhưng không hoạt động khi lên production. Tài liệu cho các tùy biến nâng cao còn thiếu, và việc khó override giao diện admin hoặc chèn thêm trang tùy chỉnh khiến trải nghiệm kém thân thiện hơn với người dùng không rành kỹ thuật.\n- Asset caching chưa tối ưu (-1). Media phục vụ qua assets.tina.io hiện chưa có cơ chế cache phù hợp. Cache chưa tối ưu này không làm hỏng điểm PageSpeed, nhưng cũng không giúp điểm số bứt phá: trên dự án Atlas Robotics, điểm Performance dừng ở mức chấp nhận được, không cao bằng khi dùng Prismic. Perxel vẫn chưa tìm ra giải pháp khắc phục triệt để, và chưa rõ đây có phải là giới hạn riêng của gói miễn phí hay không.\n\nPageSpeed Insights, bản mobile.\n\nPageSpeed Insights, bản desktop.\n\nThách thức về setup và giải pháp từ Perxel\n\nSự tự do và tiết kiệm chi phí lâu dài của TinaCMS đi kèm với thời gian thiết lập ban đầu lớn hơn khá nhiều so với các SaaS CMS thông thường. Lập trình viên phải định nghĩa toàn bộ schema nội dung, thiết lập kết nối giữa GitHub và Next.js, đồng thời tối ưu các component để tính năng Click-to-Edit hoạt động mượt mà mà không ảnh hưởng tốc độ tải trang.\n\nNhận thấy rào cản này, Perxel đã đầu tư giai đoạn R&D để đóng gói sẵn một bộ khung tiêu chuẩn cho Next.js kết hợp TinaCMS. Năng lực làm chủ kỹ thuật này được chứng minh qua chứng nhận Certified Developer từ TinaCMS (/insights/certified-tinacms-developer). Nhờ bộ khung đã tối ưu sẵn, chi phí thời gian setup không bị tính vào ngân sách của khách hàng.\n\nKhi nào nên chọn TinaCMS?\n\n- Khi team vận hành nội dung ưu tiên trải nghiệm Click-to-Edit trực tiếp trên giao diện trang.\n- Khi website cần từ 3 ngôn ngữ trở lên và muốn tránh chi phí đăng ký gói doanh nghiệp theo locale.\n- Khi doanh nghiệp muốn cắt giảm tối đa chi phí máy chủ và phí CMS định kỳ hàng tháng.\n\nLời kết\n\nPerxel lần đầu biết đến TinaCMS và triển khai thành công chỉ trong 3 ngày cho dự án Growtrics (/works/growtrics), một creative website có animation GSAP phức tạp. Khách hàng, vốn là một team kỹ thuật, không hề yêu cầu CMS, nhưng Perxel vẫn tích hợp thêm và họ rất hài lòng khi có thể tự quản lý nội dung sau đó.\n\nTừ dự án đó, Perxel xây dựng Atlas Robotics (/products/atlas-robotics) để kiểm chứng giới hạn thực tế của stack: hỗ trợ 3 ngôn ngữ, lưu trữ vài GB hình ảnh và video, demo trực tiếp tại atlas-robotics.perxel.com. Website vận hành ổn định, với điểm PageSpeed ở mức chấp nhận được như đã nêu ở trên, dù chưa vượt qua Prismic ở cùng tiêu chí.\n\nTinaCMS mang lại một lựa chọn thay thế WordPress với chi phí hạ tầng thấp cho các website marketing mà Perxel xây dựng.\n\nTìm hiểu chi tiết về dịch vụ Website Next.js & Headless CMS (/services/nextjs) của Perxel, hoặc đọc bài viết So sánh TinaCMS và Prismic (/insights/tinacms-vs-prismic) nếu vẫn còn phân vân giữa hai lựa chọn.\n\n1. TinaCMS\n2. TinaCMS: Pricing"},{"kind":"insight","locale":"vi","slug":"prismic-headless-cms","title":"Prismic & Next.js","shortTitle":null,"excerpt":"Khám phá Prismic, giải pháp Headless CMS thương mại cho Next.js với Slice Machine, revalidate tự động qua webhook, giao diện quản trị thân thiện và hệ sinh thái developer mạnh.","categories":["CMS","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"prismic","label":"Prismic"}],"date":"2026-09-15","updated":null,"dateModified":"2026-09-15","url":"https://perxel.com/insights/prismic-headless-cms","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Dịch vụ liên quan","title":"Website Next.js & Headless CMS","href":"/services/nextjs"}],"body":"Sự kết hợp giữa Next.js và Prismic là một lựa chọn phổ biến cho website doanh nghiệp và chiến dịch marketing hiện đại. Next.js đảm nhiệm phần hiệu năng, SEO và kiến trúc biên dịch, còn Prismic đảm nhiệm phần quản trị nội dung, giúp team Marketing tự xây dựng trang mà không phụ thuộc kỹ sư phần mềm.\n\nPrismic là gì?\n\nPrismic là một Headless CMS dạng SaaS, thiết kế cho việc xây dựng và quản lý các thành phần giao diện theo mô hình Page Builder dựa trên Slices. Khác với các CMS truyền thống cồng kềnh, Prismic tách biệt hoàn toàn lớp quản trị dữ liệu và lớp hiển thị giao diện của Next.js. Đây là một Headless CMS đầy đủ tính năng theo đúng nghĩa, khác với các giải pháp như TinaCMS vốn tập trung chủ yếu vào trải nghiệm chỉnh sửa trực quan.\n\nDashboard quản trị của Prismic được thiết kế hiện đại, thân thiện với cả những quản trị viên không có nền tảng kỹ thuật. Biên tập viên xem trước nội dung qua một ô preview riêng nằm kế bên (side-by-side preview) trước khi publish, thay vì chỉnh sửa trực tiếp trên giao diện trang.\n\nPage Builder của Prismic, minh họa từ dự án Foldables.\n\nDeveloper Experience: Slice Machine, CLI và Webhook\n\nVề mặt kỹ thuật, Prismic sở hữu một trong những bộ công cụ phát triển hoàn thiện nhất trong nhóm Headless CMS hiện nay.\n\n- Slice Machine. Giúp lập trình viên đóng gói các component giao diện Next.js thành từng Slice tái sử dụng. Team Marketing tự sắp xếp các Slice này để tạo landing page mới mà không làm vỡ layout thiết kế chuẩn.\n- Revalidate tự động qua Webhook. Mỗi khi publish, Prismic kích hoạt webhook gửi tín hiệu đến Next.js để làm mới cache gần như tức thì, không cần rebuild toàn bộ trang.\n- CLI và hệ sinh thái hỗ trợ. Công cụ dòng lệnh giúp tự động hóa khởi tạo dự án, đi kèm tài liệu và team hỗ trợ kỹ thuật của một nhà cung cấp SaaS quy mô lớn.\n\nGiới hạn và mô hình chi phí\n\nGói miễn phí của Prismic hỗ trợ 1 tài khoản editor, 2 ngôn ngữ và 100GB băng thông mỗi tháng, không cho phép vượt hạn mức. Mức này đủ dùng cho hầu hết website giới thiệu doanh nghiệp hoặc chiến dịch marketing thông thường.\n\nKhi doanh nghiệp cần thêm nhân sự biên tập hoặc thêm ngôn ngữ, gói Starter trả phí (khoảng $10/tháng) nâng lên 3 tài khoản editor và 3 ngôn ngữ. Các gói cao hơn tiếp tục mở rộng theo số lượng editor và locale cần thiết.\n\nĐịnh vị tại Perxel\n\nPerxel nhận thấy Next.js kết hợp Prismic là lựa chọn phù hợp cho doanh nghiệp tìm kiếm một hệ Headless CMS ổn định, giao diện quản trị dễ dùng ngay từ đầu, và không có nhu cầu quản trị nhiều hơn 2 ngôn ngữ ở quy mô ban đầu. Đối với các dự án cần triển khai nhanh, Prismic giúp rút ngắn thời gian làm quen hệ thống cho team khách hàng.\n\nNăng lực triển khai đã được kiểm chứng qua dự án thực nghiệm Foldables (/products/foldables), demo trực tiếp tại foldables.perxel.com. Điểm PageSpeed Insights đạt 92 trên cả mobile và desktop, cao hơn dự án tương đương dùng TinaCMS.\n\nPageSpeed Insights, bản mobile.\n\nPageSpeed Insights, bản desktop.\n\nTìm hiểu thêm về dịch vụ Website Next.js & Headless CMS (/services/nextjs), hoặc đọc bài viết So sánh TinaCMS và Prismic (/insights/tinacms-vs-prismic) để chọn ra giải pháp phù hợp nhất.\n\n1. Prismic\n2. Prismic: Pricing"},{"kind":"insight","locale":"vi","slug":"tinacms-vs-prismic","title":"So sánh TinaCMS và Prismic","shortTitle":null,"excerpt":"Phân tích ưu nhược điểm giữa TinaCMS (Click-to-Edit, Git-backed) và Prismic (giao diện hiện đại, agentic web platform) để chọn đúng CMS cho website Next.js.","categories":["CMS","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"tinacms","label":"TinaCMS"},{"id":"prismic","label":"Prismic"}],"date":"2026-09-15","updated":null,"dateModified":"2026-09-15","url":"https://perxel.com/insights/tinacms-vs-prismic","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Dịch vụ liên quan","title":"Website Next.js & Headless CMS","href":"/services/nextjs"}],"body":"Khi xây dựng website trên nền tảng Next.js, việc chọn Headless CMS ảnh hưởng trực tiếp đến trải nghiệm vận hành hàng ngày của team Marketing cũng như chi phí duy trì hệ thống lâu dài. TinaCMS và Prismic là hai giải pháp Perxel đưa vào danh mục kỹ thuật tiêu chuẩn, đại diện cho hai triết lý phát triển khác nhau. Bài viết này phân tích minh bạch ưu nhược điểm của từng công cụ.\n\nSo sánh nhanh\n\nTrải nghiệm biên tập\n\nTinaCMS nổi bật với khả năng xem trước và chỉnh sửa nội dung trực tiếp trên giao diện của website (Click-to-Edit). Quản trị viên nhấp trực tiếp vào đoạn văn bản hoặc hình ảnh trên trang để chỉnh sửa, không cần học một giao diện form riêng biệt.\n\nTinaCMS trước hết là một visual editor, không phải một CMS đầy đủ tính năng. Phần dashboard xung quanh (danh sách trang, quản lý collection) của TinaCMS lại khá cơ bản, chưa tinh tế bằng Page Builder của Prismic. Điều này không ảnh hưởng đến khả năng tự vận hành: sau khi Perxel bàn giao, team khách hàng vẫn tự chỉnh sửa nội dung được mà không cần đến lập trình viên, đây là tiêu chuẩn kỹ thuật Perxel luôn tối ưu trong mọi dự án triển khai TinaCMS.\n\nClick-to-Edit của TinaCMS, minh họa từ dự án Atlas Robotics.\n\nPrismic không hỗ trợ click trực tiếp trên trang. Thay vào đó, công cụ cung cấp một ô preview riêng nằm kế bên (side-by-side preview) trong trang quản trị. Đây là hai khu vực riêng biệt, nhưng giao diện quản trị của Prismic được thiết kế hiện đại và dễ thao tác với người dùng không chuyên kỹ thuật ngay từ lần đầu sử dụng.\n\nPage Builder của Prismic, minh họa từ dự án Foldables.\n\nGiới hạn và chi phí vận hành\n\nPrismic vận hành theo mô hình SaaS thương mại. Gói miễn phí hỗ trợ 1 tài khoản editor và 2 ngôn ngữ, kèm 100GB băng thông mỗi tháng không cho phép vượt hạn mức. Dung lượng asset (ảnh, video) không bị giới hạn dung lượng. Khi cần mở rộng, gói Starter (khoảng $10/tháng) nâng lên 3 tài khoản editor và 3 ngôn ngữ.\n\nTinaCMS vận hành theo mô hình Git-backed, lưu dữ liệu trực tiếp trong repository của dự án. Gói miễn phí hỗ trợ 2 tài khoản editor, không giới hạn số ngôn ngữ và không tính phí theo băng thông truy cập. Mỗi tệp tải lên qua Tina Cloud giới hạn tối đa 100MB, nhưng nếu dùng repo-based media (lưu file ngay trong repo thay vì qua Tina Cloud), dung lượng thực tế phụ thuộc vào Git host bạn dùng, không phải một hạn mức riêng của TinaCMS. Khi team biên tập lớn hơn, gói Team (khoảng $24/tháng) nâng lên 3 tài khoản editor.\n\nBackup, rollback và độ ổn định\n\nHai công cụ xử lý việc backup và phục hồi nội dung theo hai cách hoàn toàn khác nhau. TinaCMS không có nút \"quay lại phiên bản cũ\" ngay trên giao diện. Muốn khôi phục một phiên bản nội dung đã xuất bản trước đó, cần đến developer thao tác trực tiếp trên mã nguồn, đây là một điểm hạn chế rõ ràng so với Prismic. Việc sửa nội dung thông thường (lỗi chính tả, đổi ảnh, cập nhật giá) thì khách hàng vẫn tự làm được bình thường, không cần developer, chỉ riêng thao tác khôi phục về một bản cũ mới cần hỗ trợ.\n\nPrismic có sẵn một History panel ngay trong trình biên tập mỗi tài liệu, hiển thị toàn bộ lịch sử chỉnh sửa kèm diff view (phần thêm bớt được tô màu) và cho phép Restore về bất kỳ phiên bản nào chỉ với một click. Tính năng này có trên mọi gói kể cả bản miễn phí, không cần thao tác qua Git.\n\nVề độ ổn định, TinaCMS vẫn là giải pháp còn khá mới với cộng đồng và tài liệu hỗ trợ nhỏ hơn nhiều so với Prismic. Đây là một giải pháp đang hoạt động tốt cho nhu cầu thực tế, nhưng chưa trưởng thành và ổn định bằng Prismic, một nền tảng SaaS đã vận hành nhiều năm với team phát triển sản phẩm quy mô lớn.\n\nCông cụ và hệ sinh thái dành cho developer\n\nPrismic sở hữu team phát triển sản phẩm quy mô lớn và tài liệu hướng dẫn phong phú. Công cụ hỗ trợ revalidate dữ liệu tự động qua webhook, giúp trang tĩnh cập nhật gần như tức thì sau khi publish, cùng với CLI và mô hình Slice Machine để đóng gói component thành các Slice chuẩn hóa.\n\nTinaCMS lưu dữ liệu trực tiếp dưới dạng tệp Markdown hoặc JSON trong mã nguồn Git. Về mặt kỹ thuật, cách vận hành này đòi hỏi nhiều bước cấu hình ban đầu hơn Prismic: định nghĩa schema, kết nối GitHub, tối ưu để Click-to-Edit hoạt động mượt. Nhưng với khách hàng của Perxel, khác biệt này không còn ý nghĩa thực tế: cả hai bộ khung Atlas Robotics (/products/atlas-robotics) và Foldables (/products/foldables) đã được kiểm chứng sẵn, thời gian triển khai một dự án mới gần như tương đương nhau dù chọn giải pháp nào.\n\nHỗ trợ AI qua MCP\n\nPrismic vừa ra mắt một MCP Server chính thức, cho phép AI assistant như Claude hay ChatGPT tìm kiếm, đọc, tạo nội dung, tải asset và publish trực tiếp từ một cuộc hội thoại, thay vì phải mở dashboard thao tác thủ công. Đây là hướng đi rõ ràng nhắm đến người dùng không chuyên kỹ thuật: chỉ cần trò chuyện với AI để cập nhật website.\n\nTinaCMS chưa có một MCP Server tương đương. Vì nội dung của TinaCMS vốn đã là file Markdown/JSON nằm ngay trong mã nguồn, nó lại phù hợp tự nhiên với các AI coding agent thao tác trực tiếp trên codebase (như Claude Code), một hướng tiếp cận nghiêng về team kỹ thuật hơn là người dùng phổ thông.\n\nĐề xuất theo bài toán thực tế\n\nDựa trên kinh nghiệm triển khai thực tế, Perxel đưa ra lời khuyên lựa chọn theo quy mô vận hành:\n\n- Chọn Prismic khi website chỉ cần 1 đến 2 ngôn ngữ, 1 người phụ trách biên tập, và bạn muốn một giao diện quản trị chuyên nghiệp, ổn định, sẵn sàng sử dụng ngay từ đầu, kể cả thao tác qua AI assistant.\n- Chọn TinaCMS khi website cần từ 3 ngôn ngữ trở lên, nhiều hơn 2 người cùng biên tập nội dung, hoặc bạn ưu tiên trải nghiệm Click-to-Edit và chi phí vận hành thấp dài hạn, chấp nhận đánh đổi một dashboard cơ bản hơn và cộng đồng hỗ trợ còn nhỏ.\n\nLời kết\n\nKhông có CMS nào hoàn hảo cho mọi dự án, chỉ có giải pháp phù hợp nhất với mục tiêu vận hành và ngân sách của doanh nghiệp. Perxel đã kiểm chứng cả hai giải pháp qua các dự án thực nghiệm: Atlas Robotics (/products/atlas-robotics) với TinaCMS và Foldables (/products/foldables) với Prismic, cả hai đều đã test và sẵn sàng demo.\n\nTìm hiểu chi tiết về dịch vụ Website Next.js (/services/nextjs) của Perxel, hoặc đọc riêng từng giải pháp tại TinaCMS & Next.js (/insights/tinacms) và Prismic & Next.js (/insights/prismic-headless-cms).\n\n1. TinaCMS\n2. TinaCMS: Pricing\n3. TinaCMS: Repo-Based Media\n4. Prismic\n5. Prismic: Pricing\n6. Prismic: Versioning and Restoring a Document\n7. Prismic: MCP Server"},{"kind":"insight","locale":"vi","slug":"certified-tinacms-developer","title":"Certified Developer by TinaCMS","shortTitle":null,"excerpt":"Perxel chính thức nhận chứng nhận Certified Developer từ TinaCMS, đánh dấu bước chuẩn hóa bộ stack Next.js và TinaCMS qua dự án Atlas Robotics.","categories":["CMS","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"}],"date":"2026-09-14","updated":null,"dateModified":"2026-09-14","url":"https://perxel.com/insights/certified-tinacms-developer","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Hôm nay, Perxel ghi nhận một cột mốc kỹ thuật mới: Phúc Bùi (kỹ sư chính tại Perxel) đã chính thức nhận được Certified Developer badge từ team TinaCMS sau hơn một tuần review.\n\nEmail xác nhận từ Credly.\n\nBadge này nằm trong chương trình Certified Developer chính thức của TinaCMS: sau khi triển khai một website bằng TinaCMS và TinaCloud, ứng viên gửi email cho team TinaCMS kèm câu trả lời về cấu hình dự án (Client ID, quy trình pull request, cấu hình branch preview) và cách xử lý một số tình huống lỗi thực tế, trước khi được team TinaCMS xét duyệt và cấp badge qua Credly.\n\nĐây không chỉ là một ghi nhận chuyên môn cá nhân, mà còn là minh chứng cho tinh thần làm việc tại Perxel: mọi giải pháp công nghệ đưa vào dịch vụ đều phải trải qua quá trình thử nghiệm thực tế, kiểm chứng hiệu năng và làm chủ trước khi bàn giao tới khách hàng.\n\nKhởi đầu từ nhu cầu thực tế: Thử nghiệm 3 ngày với dự án Growtrics\n\nTinaCMS lần đầu tiên xuất hiện trong quy trình làm việc của Perxel tại dự án Growtrics (/works/growtrics), một creative marketing website dành cho EdTech startup tại Singapore.\n\nVì sản phẩm được bàn giao trực tiếp cho team kỹ thuật nội bộ của khách hàng, ngay từ đầu dự án không yêu cầu một hệ thống quản trị nội dung đồ sộ. Perxel lựa chọn nền tảng Next.js (/services/nextjs) để tăng tốc độ phát triển giao diện và đảm bảo hiệu năng tải trang thực tế.\n\nTrong giai đoạn chuẩn bị bàn giao, nhận thấy quỹ thời gian phát triển vẫn còn dư dả, Perxel nảy ra ý tưởng tích hợp thêm một Headless CMS tinh gọn, tương thích tự nhiên với Next.js mà không làm tăng dung lượng codebase. Mục tiêu rất rõ ràng: dù đối tác có khả năng quản lý mã nguồn trực tiếp, việc đi kèm một trình quản trị nội dung trực quan sẽ giúp sản phẩm được hoàn thiện chỉn chu hơn, mang lại sự thuận tiện lâu dài khi vận hành.\n\nPerxel đã hoàn tất quá trình nghiên cứu tài liệu, tích hợp TinaCMS và bàn giao sản phẩm chỉ trong 3 ngày. Sự kết hợp này mở ra một hướng đi mới cho các dự án marketing website tiếp theo.\n\nChuẩn hóa bộ stack Next.js + TinaCMS qua dự án thực nghiệm Atlas Robotics\n\nNhận thấy tiềm năng của sự kết hợp giữa Next.js và TinaCMS, một giải pháp phù hợp cho các website marketing hoặc landing page chiến dịch có ngân sách vừa phải, vừa đảm bảo tính năng biên tập trực quan (live preview), vừa giữ chi phí duy trì hàng tháng ở mức tối giản, Perxel bắt đầu nghiên cứu sâu hơn để đưa bộ stack này vào quy trình tiêu chuẩn.\n\nAtlas Robotics (/products/atlas-robotics) ra đời như một dự án thực nghiệm (Proof of Concept) để kiểm chứng tính khả thi của mô hình này trên quy mô lớn hơn. Qua Atlas Robotics, Perxel đã thử nghiệm khả năng xử lý hàng gigabyte dữ liệu media, cấu hình hệ thống đa ngôn ngữ (Anh, Việt, Trung) và triển khai trên hạ tầng Edge Network Cloudflare Workers (qua OpenNext) mà không phát sinh chi phí máy chủ hay cơ sở dữ liệu hàng tháng.\n\nGiá trị thực tế cho doanh nghiệp và creative agency\n\nSự kết hợp giữa Next.js và TinaCMS mang lại giải pháp cân bằng giữa hiệu năng, độ an toàn và chi phí duy trì cho các dự án quy mô vừa và nhỏ:\n\n- Tốc độ tải trang và độ an toàn cao. Website được biên dịch thành các trang tĩnh, giúp tối ưu tốc độ phản hồi và loại bỏ các nguy cơ tấn công mạng thông thường.\n- Chi phí vận hành tối giản. Dữ liệu lưu trữ dạng Git-backed trực tiếp trong repository dự án, giúp doanh nghiệp không phải gánh chi phí hosting đắt đỏ hay phí subscription hàng tháng.\n- Giao diện biên tập vừa đủ. Trình quản trị TinaCMS trực quan, tập trung đúng vào các nội dung cần chỉnh sửa mà không gây rối mắt cho người sử dụng.\n\nLời kết\n\nChứng nhận Certified Developer từ TinaCMS là lời khẳng định cho năng lực thực thi kỹ thuật và định hướng làm việc nghiêm túc tại Perxel. Quý khách hàng và đối tác có thể tìm hiểu chi tiết hơn về cấu trúc kỹ thuật và tính phù hợp của giải pháp này tại trang Dịch vụ Website Next.js & Headless CMS (/services/nextjs). Perxel sẽ tiếp tục đồng hành cùng các designer và thương hiệu để biến mọi ý tưởng thiết kế thành những sản phẩm web hoàn thiện, tối ưu và vận hành bền vững.\n\n1. TinaCMS Certified Developer badge (Credly)\n2. TinaCMS Certifications"},{"kind":"insight","locale":"vi","slug":"nectarblocks","title":"Meet Nectarblocks","shortTitle":null,"excerpt":"Perxel đã dùng NectarBlocks qua nhiều dự án WordPress custom theme thực tế. Đây là đánh giá thẳng thắn về cách Perxel thực sự dùng công cụ này khi lập trình, không phải bài giới thiệu tính năng.","categories":["WordPress","Development"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"gutenberg","label":"Gutenberg"},{"id":"nectarblocks","label":"NectarBlocks"},{"id":"pagespeed","label":"PageSpeed Insights"}],"date":"2026-09-12","updated":null,"dateModified":"2026-09-12","url":"https://perxel.com/insights/nectarblocks","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Trong hoạt động phát triển website, lựa chọn page builder ảnh hưởng trực tiếp đến hiệu năng vận hành và trải nghiệm quản trị lâu dài. Suốt một thời gian dài, các classic page builder như WPBakery hay Elementor là lựa chọn phổ biến, nhưng các công cụ này hoạt động như một hệ thống độc lập đè lên cấu trúc cốt lõi của WordPress, tạo gánh nặng mã nguồn và làm chậm tốc độ tải trang thực tế.\n\nSự ra đời của Gutenberg, page builder mặc định của WordPress, đã thay đổi cục diện. Để tối ưu trải nghiệm quản trị cho khách hàng, Perxel chuyển sang dùng NectarBlocks trong các dự án custom theme. Bài viết này là đánh giá thực tế của Perxel sau quá trình sử dụng, không phải bài giới thiệu tính năng lấy từ trang chủ nhà phát triển.\n\nMột layer bổ sung, không phải một hệ thống riêng\n\nNectarBlocks không phải một page builder độc lập làm thay đổi bản chất hệ thống. Công cụ này hoạt động như một layer bổ sung, mở rộng tính năng trực tiếp trên nền Gutenberg core. Điều này mang lại sự đảm bảo kỹ thuật lớn: người quản lý website vẫn dùng song song các block mặc định của Gutenberg, không lo website bị khóa chặt vào một page builder lạ hay gặp lỗi khi WordPress cập nhật phiên bản mới.\n\nGiao diện biên tập trong thực tế\n\nMục đích cốt lõi của NectarBlocks là cho phép dựng bố cục và kiểm soát các thuộc tính hiển thị ngay trong giao diện quản trị của WordPress. Thay vì giới hạn ở các khối nội dung đơn giản, công cụ này can thiệp sâu vào các thuộc tính CSS ngay trong khu vực soạn thảo: chia dòng, chia cột, responsive theo từng thiết bị, hiệu ứng hover, và animation.\n\nGiao diện biên tập NectarBlocks ngay trong WordPress admin: cây cấu trúc layer bên trái, canvas xem trực tiếp ở giữa, panel cấu hình style và spacing bên phải.\n\nCó thể hình dung công cụ này hoạt động tương tự Webflow ngay trên nền tảng WordPress. Người quản lý website can thiệp chi tiết vào khoảng cách (margin, padding), căn lề (flexbox, grid) và hiệu ứng trực tiếp trong khu vực soạn thảo, mà vẫn giữ được sự gọn nhẹ của mã nguồn hệ thống.\n\nTừ block có sẵn đến code riêng cho từng dự án\n\nNgoài row, column, text và image, NectarBlocks còn cung cấp một bộ block khá đầy đủ: Post Grid để hiển thị danh sách bài viết, Carousel và Marquee cho nội dung trượt ngang, Accordion, Testimonial, Icon, Video Lightbox, và một bộ block riêng cho WooCommerce. Công cụ cũng hỗ trợ animation khi cuộn trang, global styles để đồng bộ màu sắc và font chữ toàn site, và kết nối dữ liệu động qua Advanced Custom Fields (ACF).\n\nTrong các dự án custom theme (/services/wordpress-custom-theme) của Perxel, phần lớn các block này không được dùng trực tiếp. Việc phát triển một custom theme đúng nghĩa đòi hỏi lập trình viên viết mã nguồn tùy biến hoàn toàn dựa trên bản vẽ Figma để đảm bảo tính độc bản cho thương hiệu, nên Perxel không dùng các bản thiết kế dựng sẵn của NectarBlocks.\n\nPerxel chỉ dùng nhóm block layout cơ bản (hàng, cột, văn bản, hình ảnh) để định hình khung xương trang trong admin. Mọi phần đặc thù theo thiết kế, animation, testimonial hay giao diện sản phẩm, đều được lập trình riêng bằng code để hiển thị chính xác so với bản vẽ gốc, thay vì dùng bản dựng sẵn của page builder.\n\nKiểm soát SEO ngay trong block hình ảnh\n\nMột chi tiết nhỏ nhưng đáng giá của NectarBlocks nằm ở block hình ảnh. Alt text, tỷ lệ ảnh và thuộc tính liên kết (rel, target mở tab mới) đều xuất hiện ngay trong panel cấu hình, thay vì phải mở phần cài đặt riêng hoặc dễ bị bỏ qua vì không thấy field nhập liệu.\n\nPanel cấu hình block hình ảnh: Alt Text, Resolution, Image Ratio và thuộc tính liên kết đều nằm sẵn trong khu vực chỉnh sửa.\n\nAlt text là một trong những yếu tố SEO cơ bản nhưng thường bị bỏ sót nhất khi người quản lý website tự đăng bài. Đặt trường này ngay cạnh ảnh, thay vì ẩn trong một tab riêng, giúp tăng khả năng người biên tập thực sự điền vào.\n\nHiệu năng thực tế\n\nVì NectarBlocks hoạt động như một layer bổ sung trên Gutenberg core thay vì một hệ thống riêng, mã nguồn sinh ra khá gọn nhẹ. Ảnh chụp PageSpeed Insights dưới đây đo trên chính trang chủ nectarblocks.com, không phải một website do Perxel bàn giao, nhưng cho thấy phần lõi công nghệ mà công cụ này dựa vào không kéo theo gánh nặng hiệu năng đáng kể.\n\nPageSpeed Insights đo trên trang chủ nectarblocks.com.\n\nĐiểm số PageSpeed thực tế trên từng dự án còn phụ thuộc vào nội dung, hình ảnh và gói hosting mà khách hàng sử dụng sau khi bàn giao, nên đây chỉ là bằng chứng minh họa cho phần lõi công nghệ, không phải điểm số cho mọi website Perxel bàn giao.\n\nMô hình bản quyền và tính liên tục vận hành\n\nNectarBlocks là page builder trả phí theo gói năm hoặc trọn đời, không miễn phí như Gutenberg gốc. Trong các dự án Perxel triển khai, chi phí bản quyền đã được bao gồm trong chi phí lập trình ban đầu, khách hàng không cần tự chi trả hay gia hạn định kỳ.\n\nCơ chế bản quyền của NectarBlocks cũng đảm bảo tính liên tục vận hành lâu dài:\n\n- Tính năng thiết kế vẫn hoạt động bình thường. Kể cả khi hết hạn bản quyền, người quản lý website vẫn chỉnh sửa văn bản, hình ảnh, thay đổi layout hoặc tạo thêm trang mới dựa trên hệ thống block hiện có mà không bị giới hạn.\n- Giới hạn khi hết hạn bản quyền. Hệ thống ngừng nhận bản cập nhật tự động mới nhất và không truy cập được thư viện template đám mây của nhà phát triển.\n\nVới các dự án do Perxel bàn giao, giới hạn này gần như không ảnh hưởng đến vận hành, vì toàn bộ giao diện đã được viết code riêng theo thiết kế Figma độc bản, không phụ thuộc vào thư viện template mẫu.\n\nTrải nghiệm biên tập cho người quản lý website\n\n- Nhập liệu trực quan. Người quản lý website dễ dàng thay đổi văn bản, cập nhật hình ảnh hay thêm nội dung mới trực tiếp trên giao diện trực quan mà không cần biết code.\n- Bảo toàn cấu trúc giao diện. Toàn bộ logic hiển thị và phong cách thiết kế đặc thù đã được Perxel lập trình chi tiết trong mã nguồn custom của theme, nên việc cập nhật nội dung hàng ngày không vô tình làm hỏng cấu trúc hiển thị chung.\n\nKết luận\n\nNectarBlocks là công cụ hiệu quả để mở rộng năng lực của Gutenberg mặc định mà không đánh đổi sự gọn nhẹ và hiệu năng tải trang của WordPress core. Với Perxel, phần lớn giá trị nằm ở khung layout cơ bản và trải nghiệm biên tập cho khách hàng, còn mọi chi tiết thiết kế thực tế vẫn do lập trình viên viết riêng để bám sát ý tưởng gốc từ Figma.\n\n1. NectarBlocks\n2. NectarBlocks: Meet NectarBlocks\n3. WordPress: Block editor (Gutenberg)"},{"kind":"insight","locale":"vi","slug":"cross-browser-cross-device","title":"Cross-device & Cross-browser testing","shortTitle":null,"excerpt":"Một phạm vi testing rõ ràng về browser, device và screen size giúp agency và khách hàng tránh hiểu nhầm về mức độ tương thích của website, và giúp development team tập trung effort vào những môi trường thực sự quan trọng.","categories":["Design","Development"],"tech":[{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"safari","label":"Safari"}],"date":"2026-08-14","updated":null,"dateModified":"2026-08-14","url":"https://perxel.com/insights/cross-browser-cross-device","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Yêu cầu \"website hiển thị tốt trên mọi thiết bị và trình duyệt\" rất dễ trở thành một cam kết thiếu thực tế và không có giới hạn nếu không được xác định rõ phạm vi kiểm thử ngay từ đầu dự án. Sau khi bàn giao, chỉ cần một lỗi hiển thị nhỏ xuất hiện trên một thiết bị lỗi thời của khách hàng cũng có thể gây ra những hiểu lầm không đáng có.\n\nĐể tập trung nguồn lực hiệu quả nhất vào những môi trường thực sự quan trọng, Perxel luôn thống nhất rõ phạm vi kiểm thử dựa trên dữ liệu thực tế và công nghệ hiện tại.\n\nPhạm vi hỗ trợ trình duyệt\n\nPerxel ưu tiên kiểm thử và tối ưu hóa website trên phiên bản mới nhất của các trình duyệt phổ biến tại thời điểm phát triển, bao gồm Google Chrome, Safari và Microsoft Edge.\n\nViệc tập trung vào các phiên bản mới nhất giúp website được ứng dụng những công nghệ lập trình hiện đại, tối ưu hóa hiệu năng và hạn chế các lỗ hổng bảo mật.\n\nĐể đảm bảo tính thực tế, Perxel dựa trên dữ liệu thị phần từ StatCounter tại thị trường mục tiêu của dự án để xác định top 3 phiên bản phổ biến nhất của từng trình duyệt cho việc mở rộng kiểm thử. Ví dụ, dữ liệu tại Việt Nam cho thấy Chrome dẫn đầu, tiếp theo là Safari.\n\nPhạm vi kiểm thử thiết bị và kích thước màn hình\n\nWebsite không thể hiển thị giống nhau tuyệt đối trên mọi loại thiết bị tồn tại trên thị trường. Quy trình kiểm thử của Perxel tập trung vào các kích thước màn hình phổ biến nhất dựa trên tệp khách hàng mục tiêu của từng dự án.\n\n- Tại thị trường Việt Nam, màn hình desktop phân bố tương đối đồng đều ở dải kích thước 1920x1080, 1366x768 và 1280x800.\n- Với thiết bị di động, kích thước màn hình phổ biến nhất là dải độ phân giải tương đương kích cỡ 414x896.\n\nNếu dự án của bạn đã có sẵn dữ liệu người dùng thực tế từ Google Analytics 4, Perxel khuyến khích việc chia sẻ các thông số này. Báo cáo Tech Overview trong GA4 chỉ ra chính xác trình duyệt và độ phân giải màn hình mà khách hàng của bạn đang sử dụng nhiều nhất, giúp quy trình kiểm thử đạt hiệu quả thực tế cao nhất.\n\nNhóm thiết bị của người nghiệm thu\n\nDữ liệu thị trường chung không thể dự đoán chính xác một nhóm thiết bị vô cùng quan trọng: thiết bị của chính những người trực tiếp duyệt và nghiệm thu dự án.\n\nTrong một doanh nghiệp, bộ phận marketing có thể sử dụng các thiết bị đời mới, nhưng ban lãnh đạo phê duyệt dự án có thể vẫn sử dụng các thiết bị có tuổi đời vài năm, hoặc duyệt website trên màn hình trình chiếu lớn trong phòng họp. Một lỗi nhỏ chỉ xuất hiện trên thiết bị cá nhân của người duyệt vào ngày nghiệm thu có thể làm ảnh hưởng lớn đến ấn tượng của họ về sản phẩm.\n\nVì vậy, Perxel mong muốn các agency chủ động phối hợp thu thập thông tin về thiết bị thực tế mà team nghiệm thu của khách hàng sẽ sử dụng.\n\nBạn chỉ cần nhờ người phụ trách duyệt dự án truy cập vào whatismybrowser.com trực tiếp trên thiết bị của họ và chụp lại phần thông tin trình duyệt. Những thông số chi tiết về phiên bản trình duyệt và hệ điều hành này giúp Perxel chủ động cấu hình môi trường giả lập để kiểm tra và khắc phục các lỗi tương thích ngay từ trước buổi nghiệm thu.\n\nKết luận\n\nMục tiêu của quy trình kiểm thử đa thiết bị tại Perxel không phải là đưa ra lời hứa hẹn sáo rỗng về một website hoạt động không tì vết trên mọi thiết bị trong lịch sử công nghệ.\n\nMục tiêu thực tế là cùng agency xác định một phạm vi kiểm thử thông minh, dựa trên dữ liệu người dùng thực tế và công nghệ hiện tại. Điều này giúp nhà thiết kế hiểu rõ giới hạn hiển thị, lập trình viên tập trung tối đa nguồn lực tối ưu hóa các môi trường quan trọng, và đảm bảo sản phẩm bàn giao đạt chất lượng hiển thị tốt nhất trên tay khách hàng của bạn.\n\n1. StatCounter Global Stats\n2. whatismybrowser.com"},{"kind":"insight","locale":"vi","slug":"figma-handoff","title":"Figma handoff","shortTitle":null,"excerpt":"Một Figma file đầy đủ là nền tảng tốt cho development. Trong quá trình chuyển design thành website production, sự trao đổi giữa designer và developer giúp những quyết định về responsive, typography, interaction và animation được thể hiện đúng với design intent.","categories":["Design"],"tech":[{"id":"figma","label":"Figma"}],"date":"2026-08-14","updated":null,"dateModified":"2026-08-14","url":"https://perxel.com/insights/figma-handoff","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Trong quá trình chuyển giao bản thiết kế Figma thành một website hoàn chỉnh trên trình duyệt, mục tiêu hàng đầu của Perxel là bảo toàn tối đa ý đồ sáng tạo và ngôn ngữ thiết kế gốc của designer. Để đạt được điều đó, bên cạnh một tệp Figma rõ ràng, designer và nhà phát triển web cần đồng bộ hóa tư duy về responsive, typography, web interaction và cấu trúc thiết kế.\n\nFigma là tham chiếu, trình duyệt là thực tế\n\nFigma là môi trường thiết kế tĩnh, nơi designer có thể kiểm soát chính xác kích thước canvas và vị trí của từng phần tử hiển thị. Nhưng website thực tế lại là một môi trường động, hoạt động trên đa dạng kích thước màn hình, chịu ảnh hưởng bởi font rendering của từng hệ điều hành, sự khác biệt giữa các trình duyệt và các giới hạn kỹ thuật của HTML/CSS.\n\nFigma đóng vai trò là nguồn tham chiếu chuẩn xác. Ở đúng kích thước màn hình mà agency thiết kế, mục tiêu của Perxel là website hiển thị chính xác so với bản vẽ. Nhưng quan trọng hơn, website còn phải hoạt động tự nhiên khi co giãn màn hình hoặc thay đổi nội dung thực tế. Lập trình viên không chỉ đọc các thông số pixel tĩnh từ Figma mà cần thấu hiểu logic layout và ý đồ thiết kế phía sau.\n\nSự tham gia đúng lúc của dev\n\nPerxel không xem việc lập trình viên phải tham gia vào mọi quyết định sáng tạo ngay từ đầu là yêu cầu bắt buộc, bởi mỗi creative agency luôn có một quy trình làm việc riêng. Figma khuyến nghị developer được tham gia sớm, và cách tiếp cận này rất hữu ích khi design có nhiều interaction hoặc yêu cầu kỹ thuật phức tạp. Tuy nhiên, sự tham vấn kỹ thuật đúng thời điểm mới là điều mang lại giá trị lớn nhất, để tránh các rủi ro phát sinh sau khi thiết kế đã được khách hàng phê duyệt.\n\nBiết trước một giới hạn kỹ thuật hoặc độ phức tạp của một hiệu ứng web animation trước khi trình khách hàng duyệt sẽ giúp agency chủ động đưa ra các quyết định tối ưu: giữ nguyên, đơn giản hóa một phần hay điều chỉnh lại scope dự án. Perxel luôn sẵn sàng hỗ trợ tư vấn kỹ thuật bất cứ khi nào designer hoặc agency cần đến.\n\nThiết kế, responsive và production\n\nTư duy responsive tự nhiên\n\nResponsive không có nghĩa là designer phải thiết kế cho mọi breakpoint. Trong nhiều dự án, agency chỉ cần cung cấp bản thiết kế desktop và Perxel sẽ đảm nhận việc xây dựng phương án responsive tự nhiên cho các màn hình di động.\n\nThay vì chỉ đơn giản là thu nhỏ kích thước hoặc ẩn bớt các phần tử, Perxel chủ động tối ưu lại layout: thay đổi grid hiển thị, điều chỉnh khoảng cách typography, tối ưu hóa các điểm tương tác cho màn hình cảm ứng để giữ nguyên trải nghiệm và phân cấp thông tin của bản thiết kế gốc.\n\nĐồng bộ hóa typography\n\nTypography ảnh hưởng trực tiếp đến toàn bộ vertical rhythm của trang web. Chỉ một sự khác biệt nhỏ trong cách kết xuất phông chữ giữa các trình duyệt như Chrome, Safari hay các hệ điều hành macOS, Windows cũng có thể làm lệch dòng tiêu đề, thay đổi chiều cao của khối hiển thị.\n\nVì vậy, Perxel luôn kiểm tra phông chữ ngay từ những ngày đầu phát triển. Nếu sử dụng phông chữ ngoài Google Fonts, agency cần cung cấp định dạng tệp .woff hoặc .woff2 để đảm bảo hiển thị tối ưu trên môi trường web thực tế.\n\nCấu trúc design system khoa học\n\nMột tệp Figma được tổ chức tốt bằng hệ thống Components, Styles và Variables giúp lập trình viên nhanh chóng nhận diện đâu là các mẫu thiết kế dùng chung và đâu là các trường hợp ngoại lệ có chủ đích. Điều này giúp đẩy nhanh tốc độ lập trình và đảm bảo tính nhất quán khi website mở rộng lên nhiều trang.\n\nXác định rõ nguồn tham chiếu\n\nĐể tránh việc lập trình viên phải tự đoán xem khung màn hình nào là phiên bản thiết kế cuối cùng giữa hàng loạt phương án thử nghiệm trên Figma, designer chỉ cần tổ chức tệp một cách rõ ràng. Việc phân chia trang riêng cho bản thiết kế cuối, đặt tên khoa học hoặc sử dụng tính năng \"Ready for development\" của Figma sẽ giúp hai bên hiểu chung một ngôn ngữ.\n\nThiết kế dựa trên nội dung thực tế\n\nMột website thực tế hoạt động bằng nội dung sống chứ không phải các đoạn văn bản giả lập ngắn ngủi. Nội dung thật có thể dài gấp đôi hoặc gấp ba, làm thay đổi hoàn toàn độ cao của các thẻ hiển thị và phá vỡ sự cân bằng của bố cục. Việc sử dụng nội dung tương đối hoàn chỉnh ngay từ bước thiết kế trên Figma sẽ giúp website tránh được các lỗi hiển thị ngoài ý muốn khi đưa vào vận hành.\n\nNghệ thuật kể chuyện bằng web animation\n\nWeb animation là một trong những thế mạnh cốt lõi của Perxel, nhưng một trang web đẹp cần một câu chuyện chuyển động nhất quán cho toàn bộ trang chứ không phải sự lắp ghép rời rạc của các hiệu ứng riêng lẻ.\n\nHiệu ứng chuyển động cần có nhịp điệu, tốc độ và sự liên kết chặt chẽ giữa các phần của trang web. Một phần quan trọng cần chuyển động mạnh mẽ để thu hút sự chú ý, trong khi các phần tiếp theo cần sự tinh giản để người dùng tập trung vào nội dung. Ý kiến tư vấn kỹ thuật từ Perxel sẽ giúp designer biết rõ tính khả thi, mức độ ảnh hưởng đến hiệu năng tải trang và phương án tối ưu nhất cho thiết bị di động trước khi triển khai.\n\n1. Figma: Design handoff\n2. Figma: A guide to developer handoff"},{"kind":"insight","locale":"vi","slug":"no-code-vs-custom-development","title":"No-code hay Custom Development","shortTitle":null,"excerpt":"No-code không phải lúc nào cũng rẻ hơn khi tính cả vòng đời website. Đây là cách agency nên đánh giá độ phức tạp thiết kế, cấu trúc trang và vòng đời website trước khi chọn công nghệ.","categories":["Development"],"tech":[{"id":"webflow","label":"Webflow"},{"id":"framer","label":"Framer"}],"date":"2026-08-13","updated":"2026-10-10","dateModified":"2026-10-10","url":"https://perxel.com/insights/no-code-vs-custom-development","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Dịch vụ liên quan","title":"Website Next.js & Headless CMS","href":"/services/nextjs"}],"body":"Với đúng loại dự án và một team đã quen với nền tảng, Webflow hay Framer có thể giúp các creative agency triển khai website rất nhanh. Tuy nhiên, khi website có thiết kế phức tạp, nhiều trang, nhiều hiệu ứng tương tác hoặc liên tục phát triển, vận hành website đó trên no-code vẫn cần kỹ năng gần như tương đương, và đôi khi phức tạp không kém viết code.\n\nVì vậy, câu hỏi thực tế không phải là hệ thống nào tốt hơn, mà là: dự án này phù hợp với cách xây dựng và vận hành nào?\n\nKhi nào No-code là lựa chọn tốt?\n\nNo-code phù hợp nhất khi website tương đối đơn giản và team của bạn đã có kinh nghiệm với nền tảng mà họ lựa chọn.\n\n- Website ít trang, thiết kế theo chuẩn. Một website doanh nghiệp với một số trang tiêu chuẩn hoặc một website portfolio thường không cần một hệ thống code phức tạp. Nếu thiết kế không quá đặc biệt, một lập trình viên thành thạo Webflow hoặc Framer có thể triển khai và bàn giao nhanh hơn nhiều so với custom code.\n- Landing page ngắn hạn cần tạo liên tục. Một marketing agency có thể thường xuyên cần trang cho chiến dịch, trang ra mắt sản phẩm mới hoặc trang sự kiện. Sau khi bàn giao, team thiết kế hoặc marketing của agency có thể tự tạo và chỉnh sửa các trang này trực tiếp trên nền tảng mà không cần quay lại tìm lập trình viên.\n\nNhưng có một điểm cần lưu ý: no-code chỉ thực sự đơn giản khi team biết cách sử dụng nó. Để vận hành tốt một website lớn trên Webflow hoặc Framer, bạn vẫn cần hiểu về responsive layout, cấu trúc component, design system, cấu trúc dữ liệu CMS, tối ưu SEO và nhiều vấn đề kỹ thuật khác. Không cần viết code không có nghĩa là không cần kiến thức kỹ thuật.\n\nKhi nào No-code bắt đầu trở thành vấn đề?\n\nKhó khăn thường không xuất hiện ngay từ đầu. Một website 10 trang có thể rất dễ xây dựng trên Webflow. Nhưng khi quy mô tăng lên 50, 100 hoặc 300 trang, cách tổ chức component, nội dung và design system bắt đầu quyết định website có dễ duy trì hay không.\n\nThiết kế càng custom, triển khai càng khó\n\nMột bản thiết kế Figma có thể rất dễ hiểu đối với designer, nhưng không phải lúc nào cũng tương thích trực tiếp với cách một nền tảng no-code hoạt động. Khi đó, team bắt đầu phải loay hoay xử lý các vấn đề về breakpoints, nested components, override styles và cấu trúc CMS phức tạp.\n\nChi phí tăng theo số trang và CMS item\n\nCả Webflow và Framer đều giới hạn số trang và CMS item ở các gói thấp, và tính thêm phí khi vượt giới hạn đó. Custom development không tính phí theo số trang. Chi phí chủ yếu nằm ở công sức xây dựng kiến trúc ban đầu, cộng với hosting và gói Headless CMS nếu dự án dùng (các gói này cũng có giới hạn riêng).\n\nGiới hạn và giá của từng gói thay đổi thường xuyên. Hãy kiểm tra trực tiếp trên trang giá của Webflow và Framer được dẫn ở cuối bài.\n\nWebsite marketing có vòng đời dài\n\nMột website marketing chính thức thường bắt đầu từ vài chục trang, rồi phát triển thành hàng trăm trang, thêm đa ngôn ngữ và thêm nhiều hiệu ứng tương tác mới. Khi đó, kiến trúc ban đầu quyết định website có phát triển tiếp được hay không.\n\nCustom development không có nghĩa là phải nhờ lập trình viên sửa từng chữ\n\nMột lo ngại thường gặp khi chọn custom development là sau khi bàn giao, mỗi lần đổi nội dung đều phải nhờ lập trình viên. Điều này không còn đúng khi website được kết nối với một Headless CMS như TinaCMS hoặc Prismic (/insights/tinacms-vs-prismic).\n\nLập trình viên xây dựng sẵn các khối nội dung theo đúng thiết kế. Sau đó, team marketing tự tạo trang mới, sắp xếp các khối và chỉnh nội dung trong trình soạn thảo trực quan mà không cần chạm vào code.\n\nTeam nội dung sắp xếp các khối và chỉnh nội dung trong Page Builder của Prismic, minh họa từ dự án Foldables.\n\nĐiểm khác là phạm vi chỉnh sửa. Trên no-code, người chỉnh sửa có thể thay đổi gần như mọi thứ, kể cả layout. Với Headless CMS, mỗi khối chỉ cho phép đổi những gì đã được định nghĩa từ đầu, nên thiết kế vẫn giữ đúng sau nhiều tháng sử dụng.\n\nKhi nào nên chọn Custom Development?\n\nCustom development phù hợp khi website cần được xây dựng chính xác theo thiết kế và yêu cầu thực tế, thay vì phải điều chỉnh thiết kế để phù hợp với giới hạn của nền tảng.\n\n- Khi thiết kế là giá trị cốt lõi. Nếu agency bán định hướng sáng tạo và website cần thể hiện chính xác từng chi tiết đã được duyệt, lập trình viên cần kiểm soát toàn bộ phần frontend. Khi đó, nền tảng không nên là thứ quyết định website hiển thị ra sao.\n- Khi hiệu ứng tương tác phức tạp. Các dự án yêu cầu scroll-based animation, custom transitions, interactive storytelling, hoặc WebGL và 3D cần kiểm soát mã nguồn trực tiếp để giữ hiệu năng ổn định. Trang chủ website Perxel (/works/perxel-website) là một ví dụ: nước dâng theo thao tác cuộn, cá voi và máy bay giấy đều được vẽ bằng canvas và viết bằng code.\n- Khi website cần phát triển lâu dài. Website marketing hiếm khi dừng lại sau ngày ra mắt. Các tính năng mới, ngôn ngữ mới, tích hợp API hoặc các thay đổi về SEO sẽ liên tục xuất hiện. Custom development cho phép kiểm soát sâu hệ thống và nâng cấp linh hoạt theo thời gian mà không phụ thuộc vào sự hỗ trợ của bên thứ ba.\n\nCá voi trên trang chủ Perxel được vẽ hoàn toàn bằng code trên canvas và bơi theo thao tác cuộn trang.\n\nSo sánh nhanh\n\nNăm câu hỏi nên trả lời trước khi chọn\n\nCon số này quyết định gói no-code cần dùng và cấu trúc CMS cần chuẩn bị từ đầu.\n\nThiết kế càng đặc thù thì thời gian xử lý trên no-code càng tăng.\n\nNếu chỉ cần sửa chữ, thay ảnh và thêm trang theo mẫu có sẵn, Headless CMS là đủ. Nếu cần tự dựng layout mới thường xuyên, no-code linh hoạt hơn.\n\nCác nhu cầu này thường phát sinh sau ngày ra mắt, nên cần tính trước khi chọn nền tảng.\n\nVới no-code, website gắn với nền tảng đã chọn. Với custom development, mã nguồn thuộc về bạn và có thể giao cho đơn vị khác tiếp tục phát triển.\n\nNếu phần lớn câu trả lời là ít trang, thiết kế theo chuẩn và dùng trong thời gian ngắn, no-code là lựa chọn hợp lý. Nếu website lớn dần, thiết kế đặc thù và cần vận hành nhiều năm, custom development sẽ tiết kiệm hơn về sau.\n\nKết luận\n\nNo-code không phải lúc nào cũng là lựa chọn tiết kiệm hơn khi tính trên toàn bộ vòng đời của website. Custom development cần chi phí và thời gian lớn hơn ở giai đoạn đầu, nhưng cho phép kiểm soát sâu hơn phần giao diện, animation và tốc độ tải trang. Chọn cách nào phụ thuộc vào quy mô, thiết kế và vòng đời của chính dự án đó.\n\n1. Webflow Pricing\n2. Framer Pricing"},{"kind":"insight","locale":"vi","slug":"pagespeed","title":"PageSpeed Insights & Core Web Vitals","shortTitle":null,"excerpt":"Cách đọc một báo cáo PageSpeed Insights: điểm lab khác dữ liệu người dùng thật (CrUX) thế nào, từng chỉ số Core Web Vitals nghĩa là gì, ba trường hợp thật từ các website Perxel làm, và cách Perxel tối ưu tốc độ cho WordPress và Next.js.","categories":["Performance","Development"],"tech":[{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"wordpress","label":"WordPress"},{"id":"wpbakery","label":"WPBakery"},{"id":"gutenberg","label":"Gutenberg"},{"id":"nextjs","label":"Next.js"}],"date":"2026-08-08","updated":"2026-10-13","dateModified":"2026-10-13","url":"https://perxel.com/insights/pagespeed","visibility":"public","deliveredByPerxel":true,"related":[],"projects":["khatra","perxel-website"],"usedBy":[],"links":[],"body":"PageSpeed Insights là công cụ phổ biến nhất để đánh giá tốc độ website, và điểm số trên thang 100 thường được dùng như kết quả cuối cùng. Thực tế, con số đó chỉ là một lần đo giả lập. Cùng một báo cáo còn có một phần khác, ít được chú ý hơn nhưng gần với trải nghiệm thật hơn: dữ liệu từ người dùng Chrome đã truy cập website.\n\nBài viết này giải thích cách đọc một báo cáo PageSpeed, ý nghĩa của từng chỉ số, và ba trường hợp thật từ các website Perxel làm, trong đó có một trường hợp điểm số cao nhờ một mẹo mà Perxel ghi rõ ở đây. Phần cuối là cách Perxel tối ưu tốc độ cho WordPress và Next.js.\n\nMột báo cáo PageSpeed có hai phần\n\nPhần trên, \"Discover what your real users are experiencing\", là field data lấy từ Chrome User Experience Report (CrUX): số đo thật từ những người dùng Chrome đã truy cập trang trong 28 ngày gần nhất, tính ở mức 75% số lượt truy cập. Nếu trang chưa đủ lượt truy cập, PageSpeed lấy dữ liệu của cả domain (Origin). Nếu cả domain cũng chưa đủ, phần này hiện \"No Data\".\n\nPhần dưới, \"Diagnose performance issues\", là lab data: Lighthouse tải trang một lần trên một điện thoại giả lập cấu hình thấp (Moto G Power) với mạng Slow 4G, như một lượt truy cập đầu tiên, rồi chấm điểm. Điểm Performance trên thang 100 nằm ở phần này.\n\nHai phần trả lời hai câu hỏi khác nhau. Lab data cho biết trang có vấn đề gì trong một điều kiện cố định, nên hữu ích khi tìm lỗi và so sánh trước và sau một thay đổi. Field data cho biết người xem thật đã trải nghiệm trang thế nào. Khi trang có dữ liệu CrUX, đây là con số nên xem trước.\n\nCác chỉ số nghĩa là gì\n\nBa chỉ số đầu là Core Web Vitals. Một trang đạt Core Web Vitals khi cả ba ở mức tốt với 75% lượt truy cập.\n\n- LCP (Largest Contentful Paint): phần nội dung lớn nhất hiện lên sau bao lâu. Tốt là dưới 2,5 giây. Thường là ảnh banner hoặc tiêu đề lớn. LCP chậm thường do ảnh banner tải muộn (lazy load, hoặc chờ script thay ảnh), hoặc tiêu đề chờ JavaScript hay font mới hiện.\n- INP (Interaction to Next Paint): trang phản hồi thao tác nhanh đến đâu. Tốt là dưới 200 ms. Chỉ đo được từ người dùng thật. Trong lab, TBT (Total Blocking Time) là chỉ số gần nhất. INP chậm thường do JavaScript chạy quá lâu trên luồng chính.\n- CLS (Cumulative Layout Shift): trang bị xê dịch bao nhiêu khi đang tải. Tốt là dưới 0,1. Thường do ảnh không khai báo kích thước, phần tử bị JavaScript dời chỗ sau khi trang đã hiện, hoặc animation thay đổi kích thước hay vị trí bằng width, top thay vì transform.\n- FCP, TTFB và Speed Index là các chỉ số phụ. FCP là lúc nội dung đầu tiên hiện ra (tốt là dưới 1,8 giây). TTFB là thời gian chờ byte đầu tiên từ server (tốt là dưới 0,8 giây), phụ thuộc chủ yếu vào hosting và cache. Speed Index đo nội dung lấp đầy màn hình nhanh đến đâu.\n\nBa trường hợp thật\n\nBa website dưới đây do Perxel làm, đo cùng ngày 10/10/2026. Mỗi trường hợp cho thấy một kiểu chênh lệch giữa điểm lab và trải nghiệm thật.\n\nKhatra Tile: điểm lab 73, người dùng thật đạt Core Web Vitals\n\nKhatra Tile (/works/khatra) là website WordPress dùng WPBakery, đã chạy hơn 10 năm. Bản mobile chỉ được 73 điểm trong lab, với LCP 4,7 giây. Nhưng dữ liệu CrUX của cả domain trên mobile đạt Core Web Vitals: LCP 2,2 giây, INP 95 ms, CLS 0,02.\n\nKhatra Tile bản mobile, ngày 10/10/2026: dữ liệu người dùng thật của cả domain đạt Core Web Vitals, trong khi lần đo lab được 73 điểm.\n\nLab đo một lượt truy cập đầu tiên trên điện thoại cấu hình thấp với mạng chậm. Người xem thật thì dùng nhiều loại máy và mạng, và có cả lượt quay lại với cache của trình duyệt. Vì vậy điểm lab có thể khắt khe hơn trải nghiệm thật. Một điểm 73 không có nghĩa là người xem đang gặp website chậm.\n\nBản mobile của Khatra vẫn còn chỗ để cải thiện, vì Perxel chưa tập trung tối ưu riêng cho mobile. Cụ thể:\n\n- Ảnh banner chờ script mới hiện. Plugin WebP đang dùng chế độ đặt ảnh giữ chỗ trong HTML rồi thay bằng ảnh thật bằng JavaScript, nên ảnh LCP phải chờ script chạy.\n- Quá nhiều ảnh được ưu tiên tải. Mọi slide của banner, cả bản desktop lẫn bản mobile, đều có fetchpriority=\"high\", nên ảnh đầu tiên phải chia băng thông với khoảng 10 ảnh khác.\n- TTFB của người dùng thật là 1,3 giây trên mobile. Trang đã có cache trả về sau khoảng 0,1 giây, trang chưa có cache mất khoảng 0,7 giây (đo bằng curl ngày 10/10/2026). Phần còn lại là thời gian kết nối trên mạng di động.\n\nSundmd: điểm lab 99, nhưng chưa phải trải nghiệm thật\n\nSundmd là website WordPress mới, dựng bằng NectarBlocks trên Gutenberg. Bản mobile được 99 điểm trong lab, và chưa có dữ liệu CrUX vì website còn mới.\n\nSundmd bản mobile, ngày 10/10/2026: 99 điểm trong lab, chưa có dữ liệu người dùng thật.\n\nĐiểm 99 này có một phần nhờ mẹo. Ở lượt truy cập đầu tiên trong mỗi phiên, Sundmd mở bằng một màn intro: logo thương hiệu trên nền tối trong khoảng 4,5 giây, rồi hai tấm màn trượt ra hai bên để lộ trang. Màn intro là một phần của trải nghiệm thương hiệu nên được giữ nguyên. Trong lab, nó làm điểm giảm mạnh: tấm màn thu hẹp bằng width nên bị tính là layout shift (CLS khoảng 0,18), và tiêu đề chính phải chờ màn intro xong mới hiện (riêng phần chờ hiển thị của LCP là 8,3 giây).\n\nVì vậy Perxel kiểm tra user agent của request. Khi request đến từ Lighthouse, PageSpeed Insights, WebPageTest hoặc Chrome headless, server trả về trang không có màn intro và tắt animation xuất hiện của tiêu đề. Người xem thật vẫn thấy màn intro như bình thường.\n\nĐoạn code kiểm tra công cụ đo trên Sundmd (rút gọn). Filter cuối cùng rất quan trọng: nếu WP Rocket cache trang không có intro, người xem thật cũng sẽ nhận trang đó.\n\nMẹo này chỉ thay đổi điểm lab, không thay đổi trải nghiệm thật. Khi Sundmd có đủ lượt truy cập, CrUX sẽ tính cả màn intro, và Perxel dự đoán CLS của người dùng thật sẽ ở mức cần cải thiện (khoảng 0,18). Cách sửa thật là đổi animation của tấm màn từ width sang transform, giữ nguyên hình ảnh:\n\n<!-- Trước: tấm màn thu hẹp chiều rộng, Chrome tính là layout shift -->\n<div class=\"absolute inset-y-0 right-0 w-[60vw] transition-[width] duration-700\nis-page-overlay-hidden:w-0\"></div>\n\n<!-- Sau: cùng hình ảnh, tấm màn co lại bằng transform từ mép ngoài -->\n<div class=\"absolute inset-y-0 right-0 w-[60vw] origin-right transition-transform duration-700\nis-page-overlay-hidden:scale-x-0\"></div>\n\nCách sửa này chưa được áp dụng. Perxel sẽ cập nhật bài viết khi Sundmd có dữ liệu CrUX.\n\nWebsite Perxel: cùng code, 68 và 95 điểm\n\nWebsite Perxel chạy Next.js và cũng chưa có dữ liệu CrUX. Hai lần đo trên cùng một phiên bản code, cách nhau hơn 13 tiếng, cho 68 và 95 điểm.\n\nCùng một phiên bản code của trang chủ Perxel, hai lần đo PageSpeed bản mobile: 68 điểm và 95 điểm.\n\nWebsite Perxel cũng có một chỗ làm điểm lab tốt hơn thực tế: Google Analytics chỉ tải khi người dùng có thao tác đầu tiên, hoặc sau 15 giây nếu không có thao tác nào. Lần đo giả lập không cuộn hay chạm vào trang và kết thúc trước 15 giây, nên không tính phần script này, trong khi người xem thật vẫn tải nó ngay khi cuộn trang.\n\nĐọc kết quả thế nào cho đúng\n\n- Khi có dữ liệu CrUX, xem phần này trước. Như Khatra, một điểm lab trung bình vẫn có thể đi kèm trải nghiệm thật đạt chuẩn.\n- Khi chưa có CrUX, lấy trung vị của nhiều lần đo. Một lần đo có thể lệch tới 27 điểm như website Perxel.\n- Một điểm lab rất cao chưa chắc là trải nghiệm thật. Hãy mở trang bằng trình duyệt thường và xem người xem thấy gì trong vài giây đầu. CrUX cũng có giới hạn: chỉ tính người dùng Chrome đã đồng ý chia sẻ dữ liệu, và chỉ hiện khi trang có đủ lượt truy cập.\n\nTối ưu website WordPress\n\nCSS và JavaScript\n\n- Tailwind CSS trong block Gutenberg. Perxel có một workflow riêng để dùng Tailwind CSS trong các block của Gutenberg, như trên Sundmd. Các class được dùng lại giữa các block, nên file CSS cuối cùng nhỏ.\n- JavaScript theo từng component. Trên Khatra, mỗi component đăng ký file JavaScript riêng và chỉ enqueue khi component đó được render, nên trang không dùng component nào thì không tải script của nó. Với tương tác thông thường, Perxel viết JavaScript thuần thay vì thêm thư viện.\n- Chỉ dùng plugin đã kiểm chứng. Nhiều plugin tải CSS và JavaScript của chúng lên mọi trang, kể cả trang không dùng. Perxel giữ một danh sách plugin an toàn (/insights/wordpress-plugin-list) và biết rõ file nào của từng plugin cần giữ hay bỏ.\n\nHình ảnh\n\n- Chuyển ảnh sang WebP ngay trên server. Perxel Image Optimizer (/products/perxel-image-optimizer) tạo bản WebP cho thư viện ảnh mà không gửi ảnh ra dịch vụ bên ngoài.\n- Giới hạn số kích thước ảnh. WordPress tự sinh nhiều kích thước cho mỗi ảnh tải lên. Perxel chỉ giữ các kích thước khớp với breakpoint trong bản thiết kế, để srcset chọn đúng ảnh mà không sinh hàng chục file thừa.\n- Ảnh LCP được tải ngay, ưu tiên cao và có sẵn kích thước. Trên Khatra, ảnh banner đầu trang đi qua một hàm riêng:\n\n// Ảnh LCP (banner đầu trang): tải ngay, ưu tiên cao, có width/height để trang không xê dịch\nfunction px_output_lcp_optimized_image($id, $size = 'full', $class = '') {\n$meta = wp_get_attachment_metadata($id);\nreturn sprintf(\n'<img src=\"%s\" srcset=\"%s\" sizes=\"%s\" width=\"%d\" height=\"%d\" class=\"%s\" alt=\"%s\"\nfetchpriority=\"high\" loading=\"eager\" decoding=\"async\">',\nesc_url(wp_get_attachment_image_url($id, $size)),\nesc_attr(wp_get_attachment_image_srcset($id, $size)),\nesc_attr(wp_get_attachment_image_sizes($id, $size)),\n$meta['width'] ?? 0,\n$meta['height'] ?? 0,\nesc_attr($class),\nesc_attr(get_post_meta($id, '_wp_attachment_image_alt', true))\n);\n}\n\nHàm này chỉ nên dùng cho đúng một ảnh: ảnh đầu tiên của banner, ở bản hiện trên màn hình đó. Như đã nói ở trên, trang chủ Khatra hiện dùng nó cho mọi slide, nên các ảnh tranh nhau băng thông.\n\nScript bên thứ ba\n\nGoogle Tag Manager, Facebook Pixel hay chat widget không được tải ngay khi mở trang. Trên Khatra, GTM chỉ tải khi người dùng có thao tác đầu tiên, hoặc 3,5 giây sau khi trang tải xong:\n\n// Tải GTM sau thao tác đầu tiên của người dùng, hoặc 3,5 giây sau khi trang tải xong\nlet loaded = false\nfunction loadGTM() {\nif (loaded) return\nloaded = true\nwindow.dataLayer = window.dataLayer || []\nwindow.dataLayer.push({'gtm.start': Date.now(), event: 'gtm.js'})\nconst script = document.createElement('script')\nscript.async = true\nscript.src = 'https://www.googletagmanager.com/gtm.js?id=' + GTM_ID\ndocument.head.appendChild(script)\n}\nwindow.addEventListener('load', () => setTimeout(loadGTM, 3500))\nfor (const event of ['scroll', 'mousemove', 'touchstart', 'keydown']) {\nwindow.addEventListener(event, loadGTM, {once: true, passive: true})\n}\n\nThời gian chờ ngắn hay dài là một lựa chọn: chờ ngắn thì ghi nhận được nhiều lượt truy cập ngắn hơn, chờ dài thì script nằm xa thời điểm tải trang hơn. Khatra chờ 3,5 giây, website Perxel chờ 15 giây.\n\nMáy chủ và cache\n\n- Cache ở cả server và WordPress. Perxel kết hợp cache của server (như LiteSpeed trên Khatra) với WP Rocket, để trang được trả về như một bản HTML tĩnh mà không cần chạy PHP hay truy vấn cơ sở dữ liệu. Trên Khatra, trang đã có cache trả về sau khoảng 0,1 giây, trang chưa có cache mất khoảng 0,7 giây.\n- Xóa cache đúng trang khi nội dung thay đổi. Khi người quản lý sửa hoặc thêm nội dung, cache của WP Rocket và của server được xóa cho trang đó và các trang liên quan, nên nội dung mới hiện ngay.\n- Chạy được trên hosting phổ thông. Codebase custom gọn giúp website chạy tốt trên Nginx, Apache hay LiteSpeed, không bắt buộc một nhà cung cấp cụ thể.\n\nTối ưu website Next.js\n\nNext.js có cách tối ưu khác hẳn WordPress: kiểm soát JavaScript mỗi trang tải, prefetch, font, và nếu chạy trên Cloudflare Workers thì cả cách server trả trang tĩnh. Perxel ghi lại toàn bộ cách làm và số đo trong bài Tối ưu tốc độ website Next.js (/insights/nextjs-performance).\n\nHai dự án Next.js khác của Perxel, Atlas Robotics (/products/atlas-robotics) và Foldables (/products/foldables), được 84 và 92 điểm bản desktop ở lần đo dưới đây.\n\nPageSpeed Insights của Atlas Robotics, bản desktop.\n\nPageSpeed Insights của Foldables, bản desktop.\n\nCâu hỏi thường gặp\n\nĐiểm lab thấp nhưng dữ liệu người dùng thật đạt thì có cần sửa không?\n\nNên xem lab chỉ ra vấn đề gì trước khi quyết định. Với Khatra, ảnh banner chờ script và quá nhiều ảnh ưu tiên là những lỗi thật, sửa sẽ giúp người xem trên máy yếu và mạng chậm. Nhưng không cần vội vì con số 73, vì phần lớn người xem đang có trải nghiệm đạt chuẩn.\n\nVì sao Perxel không dùng mẹo user agent cho mọi website?\n\nVì nó không làm website nhanh hơn với ai cả. Trên Sundmd, mẹo này chỉ dùng để màn intro (một lựa chọn thiết kế có chủ đích) không che các vấn đề khác trong báo cáo lab. Dữ liệu CrUX vẫn tính đầy đủ trải nghiệm thật, và cách sửa đúng là đổi animation sang transform.\n\nNgoài Performance, điểm SEO trong báo cáo đo những gì?\n\nĐiểm SEO kiểm tra các lỗi kỹ thuật cơ bản: trang có cho Google lập chỉ mục không, có tiêu đề và mô tả không, đường dẫn canonical và hreflang có đúng không, ảnh có alt text và link có chữ rõ nghĩa không. Khác với Performance, điểm này không phụ thuộc vào máy đo hay tốc độ mạng, nên website làm đúng sẽ giữ được điểm tối đa ở mọi lần đo.\n\nKết quả PageSpeed Insights bản mobile của năm website do Perxel lập trình, đo ngày 13/10/2026.\n\nĐiểm tối đa chưa có nghĩa trang sẽ lên top Google. Cấu trúc trang theo từ khóa và dữ liệu cho các công cụ AI là phần việc tiếp theo, được trình bày tại SEO và GEO cho website (/services/seo).\n\nWebsite mới chưa có dữ liệu CrUX thì nên xem gì?\n\nLấy trung vị của nhiều lần đo lab, và xem từng chỉ số thay vì chỉ xem điểm tổng. Search Console cũng hiện báo cáo Core Web Vitals khi website bắt đầu có đủ dữ liệu.\n\n1. Google PageSpeed Insights\n2. Google: About PageSpeed Insights\n3. web.dev: Web Vitals\n4. WP Rocket"},{"kind":"insight","locale":"vi","slug":"wordpress-plugin-list","title":"Danh sách plugin WordPress khuyến nghị","shortTitle":null,"excerpt":"Hiệu năng website không bị quyết định bởi số lượng plugin, mà bởi chất lượng mã nguồn của từng plugin. Đây là các plugin nền tảng Perxel dùng, cùng phân tích chi phí và điều gì xảy ra khi hết hạn bản quyền.","categories":["WordPress","Development"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":"2026-08-04","updated":null,"dateModified":"2026-08-04","url":"https://perxel.com/insights/wordpress-plugin-list","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Trong cộng đồng vận hành website, một hiểu lầm phổ biến là đánh giá hiệu năng website dựa trên số lượng plugin được cài đặt. Nhiều người lo ngại việc cài thêm plugin sẽ khiến website chậm, trong khi số khác lại lạm dụng cài đặt vô tội vạ để giải quyết các nhu cầu phát sinh tức thời.\n\nThực tế, hiệu năng website không bị quyết định bởi số lượng plugin, mà nằm ở chất lượng mã nguồn của từng plugin và sự am hiểu của người thiết lập. Một website tối ưu chỉ nên cài những công cụ thực sự cần thiết cho nhu cầu nghiệp vụ, thay vì chạy theo các con số định lượng cứng nhắc.\n\nCác mức giá nêu trong bài chỉ mang tính tham khảo tại thời điểm viết. Chi phí bản quyền, gói dịch vụ và giới hạn của từng nhà cung cấp có thể thay đổi, nên hãy kiểm tra tại đường dẫn chính chủ được dẫn ở cuối bài.\n\nNhóm plugin cốt lõi\n\nNectarBlocks\n\nPage builder mở rộng cho Gutenberg, hỗ trợ tạo layout trực quan, cấu hình responsive, hover và animation sâu trong trang quản trị. Với dự án do Perxel lập trình, chi phí bản quyền đã được bao gồm trong chi phí lập trình ban đầu, khách hàng không cần chi trả thêm trọn đời website. Khi hết hạn bản quyền, giao diện editor vẫn hoạt động bình thường để chỉnh sửa nội dung và nhân bản trang, chỉ mất các bản cập nhật tự động và thư viện template đám mây. Đường dẫn chính chủ: nectarblocks.com.\n\nGravity Forms\n\nXây dựng các form liên hệ, khảo sát, đăng ký dịch vụ có logic phức tạp. Bản quyền đã được Perxel bao gồm trọn gói trong chi phí lập trình ban đầu. Khi hết hạn, toàn bộ form đã tạo vẫn hiển thị, nhận thông tin đăng ký và lưu vào cơ sở dữ liệu ổn định, chỉ mất khả năng cập nhật phiên bản và tải thêm add-on. Đường dẫn chính chủ: gravityforms.com.\n\nRank Math SEO hoặc Yoast SEO\n\nHỗ trợ cấu hình các thẻ meta, sitemap, schema và tối ưu nội dung chuẩn SEO. Bản miễn phí đã đáp ứng phần lớn nhu cầu SEO thông thường của một website doanh nghiệp. Bản trả phí chỉ cần khi có nhu cầu đặc biệt như local SEO đa địa điểm hoặc schema sản phẩm nâng cao. Khi hết hạn bản quyền, toàn bộ cấu hình đã thiết lập vẫn giữ nguyên giá trị. Đường dẫn chính chủ: rankmath.com hoặc yoast.com.\n\nSecure Custom Fields\n\nTạo các trường nhập liệu tùy chỉnh trong trang quản trị, giúp người biên tập nhập liệu đúng cấu trúc thiết kế. Đây là giải pháp thay thế chính thức cho Advanced Custom Fields bản miễn phí, và hoàn toàn miễn phí. Đường dẫn chính chủ: wordpress.org/plugins/secure-custom-fields.\n\nPerxel Image Optimizer\n\nTự động nén dung lượng hình ảnh và chuyển sang định dạng WebP mà không làm giảm chất lượng hiển thị. Đây là sản phẩm mã nguồn mở công khai do Perxel phát triển, miễn phí, đang trong lộ trình phát hành chính thức trên thư viện plugin WordPress.org.\n\nWP Rocket\n\nTạo bộ nhớ đệm tĩnh, nén và tối ưu tệp CSS/JS để đẩy tốc độ tải trang thực tế lên mức cao nhất. Đây là plugin trả phí, nhưng người vận hành hoàn toàn có thể dùng các công cụ tối ưu cache miễn phí khác trên WordPress.org, ví dụ LiteSpeed Cache nếu máy chủ hosting hỗ trợ, để tối ưu chi phí mà website vẫn hoạt động ổn định. Đường dẫn chính chủ: wp-rocket.me.\n\nNhóm đa ngôn ngữ\n\nKhi doanh nghiệp muốn tiếp cận thị trường quốc tế, dịch thuật đa ngôn ngữ là bài toán kỹ thuật lớn. Gói công cụ chính thống nhất hiện nay là WPML, đồng bộ dữ liệu bài viết, sản phẩm, hình ảnh và dịch từng chuỗi ký tự hiển thị trên giao diện theo từng ngôn ngữ. Với các dự án Perxel, bản quyền đã được bao gồm trong chi phí lập trình ban đầu.\n\nWPML là một bộ giải pháp gồm nhiều plugin bổ trợ hoạt động song song, tiêu tốn nhiều tài nguyên máy chủ. Nếu website dùng các giao diện dựng sẵn nặng nề, việc cài thêm WPML dễ dẫn đến quá tải hệ thống. Với các website custom theme của Perxel, mã nguồn được viết tối giản từ gốc nên hệ thống chịu tải tốt ngay cả khi kích hoạt trọn bộ WPML.\n\nNhóm bảo mật và sao lưu\n\nSucuri Security\n\nTheo dõi tính toàn vẹn của tệp tin, quét mã độc định kỳ và phát hiện các hành vi xâm nhập trái phép. Bản miễn phí trên WordPress.org cung cấp đầy đủ các tính năng giám sát cơ bản. Đường dẫn chính chủ: sucuri.net.\n\nGiới hạn đăng nhập và ẩn trang wp-admin\n\nGiới hạn số lần đăng nhập sai để tránh tấn công dò mật khẩu, ẩn trang đăng nhập mặc định và thiết lập các quy tắc bảo mật cơ bản. Các plugin trong nhóm này như Kadence Security hoặc Solid Security đều có bản miễn phí đáp ứng tốt nhu cầu thông thường.\n\nAkeeba Backup\n\nTự động đóng gói toàn bộ mã nguồn và cơ sở dữ liệu, lưu trữ an toàn để sẵn sàng khôi phục khi gặp sự cố. Bản Core miễn phí đáp ứng tốt nhu cầu sao lưu và khôi phục thủ công. Bản trả phí cần thiết khi doanh nghiệp muốn lịch trình tự động sao lưu định kỳ và tự động đẩy tệp lưu trữ lên các dịch vụ đám mây. Đường dẫn chính chủ: akeebabackup.com.\n\nNhóm tiện ích quản trị\n\nĐây là những công cụ nhỏ gọn, phần lớn miễn phí, giúp giải quyết các tác vụ biên tập nội dung và tùy biến trang quản trị:\n\n- White Label CMS. Tùy biến giao diện trang quản trị, ẩn các bảng tin không cần thiết và thiết lập trang Dashboard riêng cho khách hàng.\n- AddToAny Share Buttons. Tích hợp các nút chia sẻ bài viết lên mạng xã hội một cách nhẹ nhàng.\n- Regenerate Thumbnails. Tự động tạo lại các kích thước ảnh đại diện khi website thay đổi cấu hình kích thước hình ảnh.\n- Enable Media Replace. Thay thế trực tiếp một file ảnh hoặc PDF cũ bằng file mới mà không làm thay đổi đường dẫn tĩnh.\n- Better Search Replace. Tìm kiếm và thay đổi hàng loạt chuỗi ký tự trong database, ví dụ khi đổi số hotline trên toàn hệ thống hoặc thay đổi tên miền.\n- WP Mail SMTP. Cấu hình máy chủ gửi thư trung gian, đảm bảo email tự động gửi đi từ website vào đúng hộp thư đến thay vì bị đánh dấu spam.\n\nKết luận\n\nViệc lựa chọn plugin cho website WordPress không tuân theo một công thức cố định, mà phụ thuộc hoàn toàn vào nhu cầu nghiệp vụ thực tế của từng doanh nghiệp. Một hệ thống website bền vững và hiệu năng cao là hệ thống được xây trên một custom theme WordPress (/services/wordpress-custom-theme) gọn gàng, kết hợp với một danh sách plugin được chọn lọc kỹ lưỡng, minh bạch về chi phí và rủi ro bản quyền lâu dài.\n\n1. NectarBlocks\n2. Gravity Forms\n3. Rank Math SEO\n4. Yoast SEO\n5. Secure Custom Fields\n6. WP Rocket\n7. WPML\n8. Sucuri Security\n9. Akeeba Backup"},{"kind":"insight","locale":"en","slug":"seo-score","title":"The SEO score in PageSpeed","shortTitle":null,"excerpt":"The SEO score in PageSpeed Insights checks ten basic technical issues. Five sites Perxel built all score 100, yet one of them still had a canonical bug the score never caught. What the score measures, what it misses, and how to keep it after handover.","categories":["SEO","Development"],"tech":[{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"wordpress","label":"WordPress"},{"id":"nextjs","label":"Next.js"}],"date":"2026-10-13","updated":null,"dateModified":"2026-10-13","url":"https://perxel.com/en/insights/seo-score","visibility":"public","deliveredByPerxel":true,"related":["geo","pagespeed"],"projects":["khatra","perxel-website"],"usedBy":[],"links":[{"caption":"Related service","title":"SEO & GEO for websites","href":"/en/services/seo"}],"body":"A PageSpeed Insights report has three scores next to Performance: Accessibility, Best Practices and SEO. The SEO score gets little attention because most sites already score fairly high, but it is the one score Perxel commits to hitting 100 at handover. This article covers what the score checks, what we measured on five sites we built, what the score can't see, and how to keep it at 100 as new content goes in.\n\nWhat the SEO score checks\n\nThe SEO score comes from Lighthouse, which runs these checks:\n\n- The page can be indexed. No noindex tag and no robots.txt rule blocks it. This check carries the most weight: if a page is blocked, nothing else matters.\n- The page has a title and a description. The tag and the meta description are what Google usually shows in search results.\n- The page returns a successful HTTP status. A 404 or 500 page is not indexed.\n- Links have descriptive text and are crawlable. The link text says what the target page is (not \"read more\"), and the link is an tag with a real href, not a button that runs JavaScript.\n- robots.txt is valid. No malformed lines that Google could misread.\n- Images have alt text. A short description of each image, so Google and screen readers know what it shows.\n- hreflang and canonical tags are valid. On a multilingual site, each version points to the others correctly, and every page declares one official URL.\n\nUnlike Performance, none of this depends on the test machine or the network. A site that gets these right scores the same on every run, which is why it is a number we can commit to.\n\nResults on five sites we built\n\nOn 13 October 2026 we measured the homepages of five sites, two on WordPress and three on Next.js, with PageSpeed Insights on mobile and with Lighthouse 12 on both mobile and desktop. All five scored 100 for SEO.\n\nPageSpeed Insights on mobile, measured 13 October 2026. The Performance score moves from run to run; the SEO score doesn't.\n\n- The Perxel website (/en/works/perxel-website) (Next.js). Metadata, sitemap and structured data are written in code, with hreflang tags for the Vietnamese and English versions.\n- Khatra Tile (/en/works/khatra) (WordPress). A site more than 10 years old, using Rank Math for metadata, the sitemap and business details.\n- Sundmd (WordPress). A new build on NectarBlocks, using Yoast SEO for metadata, breadcrumbs and the sitemap.\n- Foldables (/en/products/foldables) and Atlas Robotics (/en/products/atlas-robotics) (Next.js). Two marketing site starters on Prismic and TinaCMS, with SEO handled in code like the Perxel site.\n\nThe two WordPress sites score 100 because the SEO plugin is configured properly and the theme doesn't undo what the plugin declares. The three Next.js sites score 100 because every tag is generated from the same data as the page content, so no page gets left out.\n\nWhat a 100 SEO score doesn't catch\n\nWhile checking these five sites, we found a bug on Atlas Robotics that Lighthouse missed: every canonical URL and every URL in the sitemap had a double slash, like atlas-robotics.perxel.com//about, and the sitemap also listed the 404 page. The cause was a trailing / in the environment variable holding the site address. Lighthouse only checks that a canonical is valid, and a URL with a double slash is still valid syntax, so the score stayed at 100. We fixed it in code by stripping the extra / before building the paths.\n\nBeyond bugs like that, the score leaves out three things that matter:\n\n- Structured data isn't scored. Lighthouse lists it but only as a manual check. To know whether your JSON-LD is right, use Google's Rich Results Test.\n- Lighthouse tests one page at a time. A homepage at 100 says nothing about product pages or posts. We check every page type before handover, since each one uses its own template.\n- Site structure and keywords are out of scope. The score doesn't know which pages a site has, which search terms each one targets or how they link to each other. That is what tells Google what the site is about, and it is usually what clients ask about most when they rebuild a site.\n\nKeeping 100 after handover\n\nTwo of the checks depend on whoever edits the content, not on the code: image alt text and link text. One new post with an undescribed image, or one \"read more\" button, is enough to drop the score.\n\n- Make alt text a required field in the CMS. On Next.js sites with TinaCMS or Prismic, we declare the image description as required in the content model. On WordPress, the theme reads alt text from the media library, and we show the content team how to fill it in on upload.\n- Write link text for the page it leads to. Instead of \"read more\", name the page or the article.\n- Re-test after any big change. When you add a new page type or change the theme, run PageSpeed on that page before it goes live.\n\nFAQ\n\nDoes a 100 SEO score get a site to the top of Google?\n\nIt doesn't guarantee it. The score only says the site avoids basic technical mistakes. Rankings also depend on whether the content answers what people search for, whether other sites mention it, and how strong the competition is.\n\nDoes the SEO score affect whether ChatGPT or Gemini cite a site?\n\nIndirectly. AI tools also need to read a page before they can cite it, so anything that stops Google indexing a page stops them too. The work specific to AI tools is in our article on GEO (/en/insights/geo).\n\nIs a low SEO score on a WordPress site hard to fix?\n\nUsually not. The common issues are missing meta descriptions, images without alt text and icon-only links with no text. Reconfiguring the SEO plugin and fixing a few spots in the theme is often enough to reach 100.\n\n1. Google PageSpeed Insights\n2. Chrome for Developers: Lighthouse SEO audits\n3. Google: Rich Results Test"},{"kind":"insight","locale":"en","slug":"geo","title":"GEO: helping ChatGPT and Gemini read your website","shortTitle":null,"excerpt":"GEO (Generative Engine Optimization) is the work that helps ChatGPT, Gemini and Perplexity read a website correctly and mention it in their answers. Five steps we take on WordPress and Next.js sites: letting AI bots in, llms.txt, structured data, a full machine-readable source and measuring traffic from AI.","categories":["SEO","Development"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"nextjs","label":"Next.js"},{"id":"claude","label":"Claude"},{"id":"chatgpt","label":"ChatGPT"},{"id":"gemini","label":"Gemini"}],"date":"2026-10-13","updated":null,"dateModified":"2026-10-13","url":"https://perxel.com/en/insights/geo","visibility":"public","deliveredByPerxel":true,"related":["seo-score","pagespeed"],"projects":["perxel-website","khatra"],"usedBy":[],"links":[{"caption":"Related service","title":"SEO & GEO for websites","href":"/en/services/seo"}],"body":"More and more people ask ChatGPT or Gemini instead of typing keywords into Google, and what they get back is a paragraph pulled together from several websites, with a few source links. GEO (Generative Engine Optimization) is the work that gets your site into those sources: AI tools can read the pages, understand them correctly and mention them in their answers. This article walks through the five steps Perxel takes on WordPress and Next.js sites, and what is already in place on our own site.\n\nHow GEO differs from SEO\n\nThe groundwork is the same. Google says AI Overviews and AI Mode rely on the same SEO basics: indexable pages, helpful content, clear structure. A site that fails the technical SEO checks (see The SEO score in PageSpeed (/en/insights/seo-score)) will struggle to be read correctly by AI tools too.\n\nThe difference is the reader. Google ranks whole pages, while an AI tool lifts individual passages into its answer. So GEO also cares whether AI bots can reach the site at all, and whether each passage still makes sense once it is taken out of the page.\n\nStep 1: check that AI bots can reach the site\n\nEach AI tool has its own bots: GPTBot and OAI-SearchBot from OpenAI, ClaudeBot from Anthropic, PerplexityBot from Perplexity. A site can block them without the owner knowing, because the block can come from three places:\n\n- robots.txt. Some themes, plugins and config templates ship with lines that block AI bots.\n- Cloudflare. Since mid-2025, Cloudflare blocks AI bots by default on newly added domains. If you want AI tools to cite your site, turn that option off in Cloudflare's bot settings.\n- Hosting and firewalls. Many hosting plans rate-limit bots, so an AI bot may get a 429 error (too many requests) instead of the page.\n\nWe check all three on every site, then read the server logs to confirm the bots actually get the content. On the Perxel site, robots.txt blocks no bot and Cloudflare lets AI bots through.\n\nStep 2: llms.txt, a summary of the site for AI\n\nllms.txt is a Markdown file at /llms.txt that lists a site's main pages with a one-line description each. It is an open proposal, not an official standard yet, but it lets AI tools see what a site contains without reading every page.\n\n- WordPress sites. Yoast SEO generates llms.txt automatically from pages and posts. Sundmd, a WordPress site we built, uses it.\n- Next.js sites. The file is generated from the same data as the page content, so it always matches the CMS. On the Perxel site, llms.txt lists every page, service, project and article. On Foldables (/en/products/foldables), it also states that phone specs and prices are sample data, so AI tools don't quote them as official figures.\n\nStep 3: structured data\n\nStructured data (JSON-LD) describes a page in a shared vocabulary, Schema.org: this is a business at this address, this is an article by this author, published on this date. Google uses it for richer search results, and AI tools can read it without guessing from the layout.\n\n- Khatra Tile (/en/works/khatra) uses Rank Math to declare the business address and coordinates, with hreflang tags for the Vietnamese and English versions.\n- Sundmd uses Yoast SEO to declare the organisation and each page's breadcrumbs.\n- The Perxel site declares the studio, its services and the person in charge in code, and each article adds its author and last update date.\n\nOnce declared, check it with the Rich Results Test, since the SEO score in PageSpeed doesn't cover it.\n\nStep 4: a full machine-readable source\n\nllms.txt and JSON-LD are summaries. On a Next.js site we can go further and publish the whole content as a separate source for machines. The Perxel site has two:\n\n- /content.json: every page, service, project, product and article in both languages, with full text and pricing. It is rebuilt every time the site updates.\n- An MCP server: it lets AI apps like Claude search and read the site's content directly instead of downloading page after page.\n\nThe same source is where Ask Perxel, the assistant on our site, looks for answers to visitors' questions. So what visitors ask on the site and what AI tools read come from the same content.\n\nStep 5: write passages AI can quote\n\nSince AI tools take passages rather than whole pages, each passage should answer a question on its own:\n\n- Answer in the first paragraph. The page's main question is answered in the first two or three sentences, with the detail after.\n- Headings say what follows. A heading like \"Hosting costs for a Next.js site\" is more likely to be used as a source than \"Costs\".\n- Numbers come with a date and a source. A figure with the date and method of measurement is more credible than a bare one, to readers and to AI tools alike.\n- An FAQ section. Each question with a short answer is a passage ready to be quoted.\n\nMeasuring traffic from AI\n\nGEO is new, and AI tools don't publish how they pick sources. The most reliable measure today is real visits: when someone clicks a source link in an answer, the visit comes from chatgpt.com, perplexity.ai or gemini.google.com. We set up a dedicated channel group for these sources in Google Analytics, so a business can see how many visitors GEO brings and which pages they land on.\n\nFAQ\n\nShould I block AI bots to protect my content?\n\nIt depends on what the site is for. If the content is what you sell (paid articles, courses), blocking AI bots makes sense. If the site is there to present your business and win clients, letting AI bots read it helps you show up in ChatGPT and Gemini answers. According to OpenAI's documentation, you can block the bot that collects training data (GPTBot) while still allowing the search bot (OAI-SearchBot).\n\nCan a WordPress site do GEO?\n\nIt can. Rank Math and Yoast SEO already handle structured data, and Yoast can generate llms.txt automatically. What's left is checking that the hosting doesn't block AI bots and rewriting content as in step 5.\n\nHow long until AI tools mention my site?\n\nThere is no fixed timeline. AI tools that search the web can pick up a new page within days or weeks, much like Google. What a model already knows only changes when its developer trains a new version, and that is not something you can influence.\n\n1. Google Search Central: AI features and your website\n2. Cloudflare: Content Independence Day\n3. llms.txt\n4. Schema.org\n5. Google: Rich Results Test\n6. OpenAI: Overview of OpenAI crawlers"},{"kind":"insight","locale":"en","slug":"claude-for-startups","title":"Perxel approved for Claude for Startups","shortTitle":null,"excerpt":"Anthropic has approved Perxel for the Claude for Startups program, with API credits, a year of Claude Team and offers from companies building on Claude.","categories":["Development"],"tech":[{"id":"claude","label":"Claude"}],"date":"2026-10-13","updated":null,"dateModified":"2026-10-13","url":"https://perxel.com/en/insights/claude-for-startups","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"On 10 October 2026, Anthropic approved Perxel for the Claude for Startups program, its program for startups building products on Claude.\n\nAccording to the Claude Startups team, this round brought in 21 times as many applications as the program had received in its first five months, so every application was reviewed again before it was confirmed.\n\nThe confirmation email from the Claude Startups team.\n\nWhat the program includes\n\nMembers get the following (the program page has the exact terms and amounts):\n\n- API credits for the Claude API. They work on Anthropic's own API only, not through AWS Bedrock or Google Vertex AI.\n- A year of Claude Team for teams new to the Team plan.\n- The Startup Stack: offers and credits from other AI companies building on Claude, redeemed with codes in the Claude Console.\n- Higher API rate limits, and office hours every other week with Anthropic's Applied AI team.\n\nWhere we already use Claude\n\nClaude was in our products before we joined:\n\n- Ask Perxel, on this website. Press ⌘K (or the Ask Perxel button) and ask a question: Claude Haiku writes the answer from the site's own content, with sources you can open. We packaged the search and chat as @perxel/spotlight on npm.\n- Perxel AI Translate (/en/products/perxel-ai-translate), a WordPress plugin that bulk-translates WPML posts with the AI model you pick through OpenRouter, Claude included.\n\nWhat it means for us\n\nPerxel is a web tech studio that works AI-native: seven years of web experience, combined with AI in our daily work, so an idea gets from prototype to finished product faster.\n\nSo for us, this program is more than free Claude usage. The cost it takes off our plate lets us:\n\n- Test more before we choose an approach for a project.\n- Build more of our own products, like the plugins and tools on our Products (/en/products) page.\n- Run the loop faster, from idea to prototype to finished product.\n- Grow the whole team's skill with AI, and bring what we learn to client projects.\n\nFor a startup like ours, the savings are huge. Thank you, Anthropic and the Claude Startups team.\n\nIf you want an assistant on your own website that answers from your content, like Ask Perxel, talk to us (/en/contact).\n\n1. Claude for Startups program (Anthropic)"},{"kind":"insight","locale":"en","slug":"brevo-newsletter","title":"An automatic newsletter with Brevo","shortTitle":null,"excerpt":"The site publishes a post, and the next morning subscribers get an email about it. Nobody writes or sends anything. How to set up an automatic newsletter on Brevo's free plan, and why it suits marketing agencies and independent designers and developers.","categories":["Development"],"tech":[{"id":"brevo","label":"Brevo"},{"id":"cloudflare","label":"Cloudflare"},{"id":"nextjs","label":"Next.js"}],"date":"2026-10-11","updated":null,"dateModified":"2026-10-11","url":"https://perxel.com/en/insights/brevo-newsletter","visibility":"public","deliveredByPerxel":true,"related":[],"projects":["perxel-website"],"usedBy":[],"links":[],"body":"A newsletter is the simplest way to bring readers back to a website. They leave their email once, and every new piece of content finds them. The catch is that someone has to write and send each email, and that job usually gets dropped after a few weeks.\n\nBrevo, an email marketing platform with a free plan, can do that job for you. When the site publishes a post, subscribers get an email about it the next morning. Nobody writes the email or presses send.\n\nThe first half is for agencies and content managers: how it works, what it costs and what your team does once it is set up. The technical details are at the end.\n\nHow it works\n\n- Readers sign up with a form at the bottom of the page. They enter their email, tick the privacy policy box and submit. Brevo sends a confirmation email, and the address joins the list only after they click the link in it. This is called double opt-in, and it keeps typos and addresses signed up by someone else off the list.\n- New posts go out the next morning. Every day at a time you choose, Brevo reads the site's list of posts. If anything is new since the last run, it builds an email with each post's image, title, summary and a read-more button, and sends it to the whole list.\n- No new post, no email. Subscribers only hear from you when there is actually something new.\n- A multilingual site can keep one list per language. People who sign up on the Vietnamese pages get only Vietnamese posts, people on the English pages only English ones.\n- The schedule can change. Instead of daily, Brevo can group new posts into one email a week or a month. That suits sites that publish a lot, or clients who don't want to email too often.\n\nThis is our real signup form, built the way this post describes. You can subscribe right here.\n\nWho it suits\n\nMarketing agencies running client websites. The content team publishes as usual and the newsletter follows on its own. Nobody has to write an email per post, and the client gets one more channel that brings readers back to the site. The Brevo account and the subscriber list belong to the client.\n\nIndependent designers and developers with a blog or portfolio. At a few hundred subscribers, Brevo's free plan is enough, so you get a newsletter without a monthly bill.\n\nWhat it costs, and the free plan's limits\n\nFor most small sites, Brevo's free plan is enough. What to know before you pick it:\n\n- Up to 300 emails a day, across all lists. On a daily schedule each subscriber gets one email, so the free plan covers about 300 subscribers. A weekly schedule has the same ceiling, because the whole list is emailed on the same day.\n- Every email carries a \"Sent with Brevo\" line at the bottom, and the free plan doesn't let you remove it.\n- The feature that emails new posts (RSS campaigns) is on the free plan. Several other newsletter services only offer it on paid plans.\n\nPast that, Brevo's paid plans are priced by the number of emails sent per month. Prices and limits change, so check Brevo's pricing page before you choose.\n\nBrevo's pricing page on 11 October 2026, showing yearly prices.\n\nOnce it is set up, your team only manages the list\n\nThe setup covers the signup form, the post feed Brevo reads, an email template in your brand and the schedule. Once those run, the day-to-day work happens entirely in Brevo:\n\n- See who subscribed, export the list or remove someone.\n- See how many people opened each email and clicked through to a post.\n- Change the schedule, or pause the newsletter when needed.\n\nThe subscriber lists page in Brevo.\n\nSubscribers leave with the unsubscribe link at the bottom of every email, so nobody handles unsubscribe requests by hand.\n\nThe setup is actually fairly simple. If your site or a client's needs a newsletter like this, we can set it up and hand the account over so your team manages the list. Get in touch (/en/contact) to talk it through.\n\nTechnical details\n\nThis part is for developers who want to set it up themselves. The approach works for any site with an RSS feed, whether it runs WordPress, Next.js or something else.\n\nThe RSS feed is the source\n\nBrevo doesn't read the website itself. It reads an RSS feed, an XML file listing posts newest first. Each item needs a title, a summary, a share image and a publish date. On a multilingual site, give each language its own feed (for example /feed.xml and /en/feed.xml). WordPress ships with an RSS feed, so on a WordPress site this step is close to free.\n\nIn Brevo, each feed is wired to a subscriber list and an email template through the RSS campaign feature. It is an integration under Brevo's Integrations menu, not part of the API, so it is set up in the dashboard.\n\nAn RSS campaign's settings: feed, template, recipients and schedule.\n\nBuild your own signup form instead of embedding Brevo's script\n\nBrevo offers an embeddable form, but it loads Brevo's script on every page. A lighter option is your own form: it posts to the site's server, which calls Brevo's double opt-in API (POST /v3/contacts/doubleOptinConfirmation) with the right list. Pages load nothing from Brevo. If you like, the server can also ping Slack or Discord on every signup.\n\nKeep the Brevo API key in a secret environment variable on the server, never in the code.\n\nBrevo picks posts by publish date\n\nOn each run, Brevo takes the items whose publish date (pubDate in the feed) falls between the previous run and this one. With a 6:30 schedule, that is from 6:00 the day before to 6:00 that morning. If your feed takes the publish date from a date set in the post (a date field in the frontmatter, say), then:\n\n- A post pushed to production on the day in its date goes out at 6:30 the next morning.\n- A post with a date earlier than the day it actually went live is never sent, because Brevo has already read that window.\n- Editing an old post doesn't send it again.\n\nSo pick a run time earlier than when you usually publish. With Brevo's default 8:30 schedule the window ends at 8:00, so a post pushed after 8:00 on its own date would be skipped.\n\nCommon setup mistakes\n\n- An empty list makes the run fail. If a list has no confirmed subscriber yet, Brevo builds no email and sends you a 400 error email instead (\"no contacts associated with the given recipients\"). That email can't be turned off. The fix is to add your own address to every list: the lists are never empty, and you get a copy of every send.\n- The IP allowlist blocks every API call. Brevo can restrict an API key to a set of IP addresses. Serverless platforms such as Cloudflare Workers call out from changing IPs, so with that option on, every call is refused with \"unrecognised IP address\". On those platforms it has to stay off for API keys.\n- Sending from a Gmail address gets rejected. Brevo needs to send from an authenticated domain (SPF, DKIM, DMARC). Authenticate your site's domain and send from an address on it, like hello@yourdomain.com.\n\nThe email template lives in the code\n\nThe template can be HTML in the site's repo, pushed to Brevo through the API, rather than edited in Brevo's drag-and-drop editor. Each post is a card with the share image, title, summary and a read-more button, and ends with why the reader got it and an unsubscribe link. To change the design, edit the file and push again, so the live template always matches the code.\n\nBeyond the code, the site's privacy policy needs a newsletter section too: what is stored, who sends the email, open and click tracking, and how to unsubscribe.\n\n1. Brevo: Pricing\n2. Brevo Help Center: RSS campaign integration"},{"kind":"insight","locale":"en","slug":"nextjs-performance","title":"Next.js performance","shortTitle":null,"excerpt":"What we did to make our own animation-heavy Next.js site load fast, grouped by area: measuring, UI, code, assets, third-party scripts and hosting on Cloudflare Workers. Every item comes with before and after numbers and how they were measured.","categories":["Performance","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"react","label":"React"},{"id":"cloudflare","label":"Cloudflare"},{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"gsap","label":"GSAP"},{"id":"vercel","label":"Vercel"}],"date":"2026-10-10","updated":null,"dateModified":"2026-10-10","url":"https://perxel.com/en/insights/nextjs-performance","visibility":"public","deliveredByPerxel":true,"related":[],"projects":["perxel-website"],"usedBy":[],"links":[],"body":"Next.js gives you a lot for speed out of the box: prerendered pages, JavaScript split per route, image and font optimisation. An animation-heavy site can still be slow if you don't watch each part, though, and running on Cloudflare Workers instead of Vercel adds work that Next.js doesn't do for you.\n\nThis is what Perxel did to speed up our own website (/en/works/perxel-website), grouped by area: measuring, UI, code, assets, third-party scripts and hosting. Every item has before and after numbers and the conditions they were measured in. The site runs Next.js 16, React 19, GSAP and a lot of canvas, on Cloudflare Workers through OpenNext. Most of it applies to any Next.js project; the hosting part is for sites on Cloudflare.\n\nMeasure before you fix\n\nA PageSpeed score moves from run to run, so a single number can't tell you whether a change worked. The two runs below tested the same build of our homepage, a little over 13 hours apart: the first scored 68, the second 95.\n\nSame code, two PageSpeed mobile runs: 68 at 20:12 on 9 October 2026 and 95 at 09:36 on 10 October 2026.\n\nSo we measure by a few rules:\n\n- Run Lighthouse locally, on the same version PageSpeed uses. PageSpeed Insights currently runs Lighthouse 13.5 with simulated throttling. The same version on your own machine gets close to PageSpeed and has no API quota.\n- Take the median of several runs. On 10 October 2026, three mobile runs against production gave 86, 91 and 93, and two desktop runs gave 96. When comparing two versions, we run them in alternating pairs so both face the same machine conditions.\n- Check LCP with real throttling when the number looks off. Simulated mode charges every request that starts before LCP to the LCP itself. Once it reported an LCP of 4.6 s where real throttling (--throttling-method=devtools) measured 1.8 s.\n- Check PageSpeed's machine before blaming the code. PageSpeed once gave us 47 and 58 while the same Lighthouse version on our machine gave 83 to 98 for the same page. A TBT five to ten times higher usually means the test machine is slow or busy. It's listed under \"CPU/Memory Power\" at the bottom of the report.\n- Look at layout-shifts before the CLS score. One shift can be the whole score. Lighthouse with --save-assets keeps the trace, which records where each shifted element was.\n- To see what happens during load, instrument the page. We drive headless Chrome over the DevTools Protocol and inject a script that runs before anything else, logging animationstart, DOM changes and every startViewTransition call. That's how we found the view transition problem in the Code section below: neither the score nor CLS showed it.\n\nHow lab scores differ from real-user data (CrUX) is covered in PageSpeed Insights & Core Web Vitals (/en/insights/pagespeed).\n\nUI: what people see first has to arrive first\n\nThe LCP element doesn't wait for JavaScript\n\nThe big headline on our homepage is the LCP element. In the first version it came in through GSAP, so it waited for JavaScript to load and run: mobile LCP was 8.7 seconds. Now the text fits its box with CSS (cqw over the line's width in em), the entrance is CSS keyframes, and a small inline script only reveals the block once the heading font has loaded (1.2 seconds at most). LCP dropped to about 1.8 seconds, the same as FCP.\n\nTwo details are easy to miss. First, the letters start at 1% opacity, not 0, because Chrome doesn't count an element first painted at opacity 0 as an LCP candidate. Second, the inline script sits at the end of the text block: the browser may paint while it waits on the script, so anything after it would pop in late and shift the centred headline.\n\nThe headline shows as soon as the page loads; the Lottie character comes in after.\n\nStarting states live in CSS\n\nServer HTML is painted before React hydrates. So if a useLayoutEffect changes the layout afterwards, visitors still see the page jump. On our homepage the hero pulls the blue band below it up by a screen with margin-top, for the rising water effect. At first JavaScript did that, and production CLS was 0.9 on mobile and 0.64 on desktop. Once the default moved into CSS (with JavaScript only overriding it afterwards), CLS went to 0.\n\nThe rule: any layout that JavaScript changes needs its starting state in CSS. Change that element's size and you change the CSS too.\n\nA lighter UI on phones\n\nOn phones we keep the same content but swap a few heavy effects for lighter versions:\n\n- The hero character has an inline SVG poster. The Lottie animation needs 486 KB of WASM, so below 768px the character's slot shows its first frame as inline SVG (22 KB, 9.6 KB gzipped) and switches to the Lottie once it's ready. Our first attempt used a WebP image, which then became the LCP element instead of the headline. Inline SVG isn't an LCP candidate.\n- Water edges on touch screens are CSS, not canvas. On desktop the water edge is a canvas that reacts to the cursor. Phones have no cursor, so they get a wave-shaped mask slid sideways with transform, with no script running per frame.\n- The tech logo band has a lite mode on phones. The water canvas draws at 1x pixel density, the logo discs get a flat 1px ring instead of an 18px blurred shadow, and the physics steps every other frame.\n- Portrait screens get a plain project list. The row of cards that bends like a wave on canvas only runs on landscape screens at least 600px tall. Phones and upright tablets get a vertical list.\n- Pinned sections use position: sticky, not GSAP's pin: true. A GSAP pin switches the element to position: fixed and moves it from JavaScript, which trails native scrolling on iOS Safari and jitters. With sticky, the browser holds the element and ScrollTrigger only drives the animation from the scroll position.\n\nHeavy sections further down set up late\n\nThe canvas sections near the bottom of the page still create their pins and layout up front, because layout must not change later. Only the drawing and loading wait. The project cards load their images and video only once you scroll within about two screen heights of them. The pour title and the whale (font, letter layout, WebGL) set up 1.5 seconds after the page has loaded, or earlier on the first scroll, touch or key press. Before this, a 1.2 MB project video downloaded on page load even though it was several scrolls away.\n\nHomepage, mobile. LCP measured with Lighthouse under real throttling, CLS on production PageSpeed, bytes during load in headless Chrome with a 4x CPU slowdown (October 2026).\n\nCode: each page loads only the JavaScript it needs\n\nA server component can still pull client components into the page\n\nNext.js puts every client component in a server component's module graph into that page's scripts, rendered or not. Our footer reads the list of posts on every page, and that list got its frontmatter by importing the MDX files. So every client component any post used (dialog, accordion, lightbox, Lottie player) shipped in every page's JavaScript: 5 to 18% of each page's JS.\n\nThe fix was to read frontmatter from JSON instead of MDX. A script that runs before next dev and next build writes every post's frontmatter to content/meta.generated.json, and only each post's detail route imports its MDX. This was the biggest single cut. To check whether a page loads code it doesn't use, search the chunks listed in its HTML for a component's class name.\n\nAn import behind a false flag still ships\n\nOur old full-screen menu was switched off with a false constant, but Header still imported it. The bundler kept that import, so the animated cursor character and all its moods shipped on every page, on every device. In the same way, a single import of an old section that no longer rendered was enough to put the motion library on the homepage. Import a switched-off component with next/dynamic, or drop the import.\n\nCode for one kind of device loads only on that device\n\nThe bottom navigation dock is only used below 1024px, the animated cursor only with a mouse, and Lenis (smooth scrolling) only with a scroll wheel. Each is its own chunk, loaded after hydration and only on the devices that use it: next/dynamic with ssr: false behind useMediaQuery, or import() inside an effect. The dock alone took 33 KB brotli off desktop.\n\nAfter each build, check that every /_next/static path in the HTML exists. Once Turbopack emitted a preload for a chunk that didn't exist, which 404ed on post pages.\n\nLinks that are always on screen don't prefetch on sight\n\nBy default, Next.js prefetches a route when the link enters the viewport. Our header and footer link to every page, so the homepage downloaded the JavaScript of every other page right after it opened. We wrote our own link component that prefetches only on hover, focus or touch. Lighthouse's \"unused JavaScript\" went from 110 KiB to 22 KiB. The buttons on the first screen use it too, because a prefetch during load can end up waiting for the server to start (see Hosting).\n\nView transitions wait for the first interaction\n\nWith the default auto, React's ran a transition for each update after hydration. On production there were three in the first 1.5 seconds, each a 300 ms cross-fade of a page snapshot over the live page, so the header and hero looked rendered twice. CLS stayed at 0, so the only way to see it was to log the startViewTransition calls. Now view transitions turn on only after the visitor's first interaction. Navigation always follows an interaction, so page transitions still work.\n\nJavaScript each page loads (brotli, 9 October 2026) and Lighthouse's \"unused JavaScript\" on the homepage. Splitting code per device later took another 27 KB off the homepage on phones, and 18 to 19 KB off every other page.\n\nAssets: fonts, images and video\n\n- Self-host fonts and keep only the characters you use. With next/font/google, a Vietnamese page also pulled the latin-ext subset, because ă, đ, ơ and ư fall inside its range: 7 font files, 218 KB before LCP. Now Inter and Manrope are one file each, cut with pyftsubset to the Latin and Vietnamese ranges: Inter 53 KB, Manrope 29 KB.\n- Any font in the DOM loads with the page, even at the very bottom. Geist was only used for a few numbers in the services list, yet it was 29 KB at load, and FCP came out at either 1.21 or 1.66 seconds depending on whether that request started before or after the first paint. The numbers moved to Inter with tabular-nums and Geist left the project.\n- Images are close to the size they're shown at. Logos are capped at 128px, logos in the tech badges (shown at 24px) have their own 48px copies (the set went from 76 KB to 25 KB), project thumbnails are at most 1100px wide, and sizes stays close to the real slot width.\n- A video's poster is a sized , not the poster attribute. The poster attribute has no srcset, so phones downloaded an 1100px image for a 365px slot.\n- Videos are re-encoded for the size they're shown at. Project videos are encoded at 1120px, crf 34, no audio, with faststart: 20.5 MB down to 6.5 MB in total. A hidden video copy kept only for layout has preload=\"none\" so it doesn't download twice.\n\nFont bytes before LCP on a Vietnamese page, total size of the project videos, and the tech badge logo set (October 2026).\n\nThird-party scripts\n\nGoogle Analytics and Cloudflare Web Analytics load on the visitor's first interaction (scroll, mouse move, touch, key press, click), or after 15 seconds if there is none. The wait used to be 8 seconds, which PageSpeed's run reached, loading gtag (172 KiB, 70 KiB of it flagged as unused).\n\nWe're open about this because it shows the limit of a lab score: the simulated run never scrolls or touches the page and finishes before 15 seconds, so it never counts these scripts. A real visitor loads them as soon as they scroll, after the page is already visible. The cost is that someone who leaves within 15 seconds without doing anything isn't counted. We installed the Cloudflare Web Analytics script by hand instead of letting Cloudflare inject it, because the automatic injection loads it with the page.\n\nHosting: Cloudflare Workers doesn't do what Vercel does by default\n\nOn Vercel, a prerendered page is served from the edge cache without starting the app. On Cloudflare, OpenNext packs the whole Next.js app into one Worker (17.5 MB in our case), and every request goes through it, including a request for HTML that was prerendered at build time.\n\nThe Worker has to start on the first request\n\nOn a low-traffic site, the Worker usually isn't already running near the visitor. In one Lighthouse run on production, the HTML took 2.84 seconds to start arriving, and every other request waited for it. On a single connection, the first HTML request waited 0.73 seconds and the next nine only 0.09 to 0.19 seconds, the same as a static CSS file. PageSpeed always measures a first visit, and so does everyone arriving from Google.\n\nA small Worker in front of Next.js\n\nWe put a Worker of about 40 lines, with no Next.js code, in front of the OpenNext Worker. When a browser loads a prerendered page (GET or HEAD, no RSC or Next-Router- header, no _rsc parameter), it answers with the HTML copy stored in static assets, with the same headers OpenNext sends. Everything else (navigation data inside the site, forms, API, images, OG images, 404 pages, redirects) goes on to the OpenNext Worker through a service binding. It's the same idea Vercel and OpenNext on AWS use for static pages, but OpenNext on Cloudflare doesn't offer it yet, so we wrote it ourselves.\n\nA request's path: the static asset layer, the small Worker in front, and only then the Next.js app.\n\nServer wait on production, measured with curl on 10 October 2026, 8 requests of each kind within the same minute. The two kinds aren't identical: page HTML goes through the small Worker, navigation data (RSC: 1) goes to OpenNext.\n\nThe small Worker relies on Next.js and OpenNext internals, not public APIs: the headers the router sends when it fetches navigation data, the build output layout, and the headers OpenNext sends with a page. If an upgrade changes them, links inside the site can break while the build still passes. So after every Next.js or OpenNext upgrade we run both Workers locally and go through a checklist: is the page served by the small Worker, does an RSC request reach OpenNext, is the HTML byte-identical to OpenNext's, are 404s and redirects right. After every deploy a script checks the same points on production. If something breaks, pointing the domain back at the OpenNext Worker takes seconds, since it still serves the whole site on its own.\n\nOther Workers settings\n\n- Long-term caching for /_next/static. Files there have a hash in their name, so they can be max-age=31536000, immutable in _headers. The default is max-age=0, must-revalidate, so every repeat visit revalidated each chunk.\n- Turn on the IMAGES binding for /_next/image. Without it OpenNext serves the original image unresized: Lighthouse once flagged a 1440px image in a 634px slot.\n- No requests to OpenNext during load. Anything not prerendered (/api/, navigation data) wakes the OpenNext Worker, which sometimes takes 1 to 3 seconds. The status badge in our footer used to call its API twice on page load. Now it calls once, 1.5 seconds after load or on the first interaction.\n- No file reads at runtime. Workers has no disk, and OpenNext may re-run a static page's module when the cache is empty. An fs.readdirSync that works in next build will throw in production. Our post lists are written out in code.\n\nTried and dropped\n\n- experimental.inlineCss. FCP under real throttling went from 2.1 to 0.8 seconds, but the PageSpeed score fell from 88 to 83 and simulated LCP rose by about a second. The CSS gets inlined twice (in the HTML and in the RSC payload), and simulated mode charges the bigger HTML to the LCP.\n- A Cloudflare Cache Rule for HTML. When a route has a Worker, the Worker runs first and the Cache Rule does nothing. If it did work it would be risky anyway: cached HTML would point at chunks removed by the next deploy.\n- Deferring GSAP until after the hero. GSAP was only 44 KB of the 601 KB requested before LCP, against about 30 modules to change. We measured first and decided against it.\n- Serving HTML from static assets inside the big Worker. This was only about 55 ms faster at the median, because the big Worker still had to start. That test took the median of mostly warm requests, so it couldn't see the start-up cost. The small Worker above fixes exactly that.\n\nChecklist for the next Next.js project\n\n- Measure with the Lighthouse version PageSpeed uses, take medians, compare in pairs, and confirm LCP with real throttling.\n- The LCP element shows with HTML and CSS, without waiting for JavaScript.\n- Any layout JavaScript changes has its starting state in CSS.\n- On phones, swap heavy effects for lighter versions instead of just hiding them with CSS.\n- Heavy sections lower on the page load their data only when the visitor gets close or first interacts.\n- Check the client components in the module graph of every shared server component (layout, header, footer).\n- Code for one kind of device lives in its own chunk, behind useMediaQuery or import().\n- Links that are always on screen prefetch only on intent.\n- Fonts are self-hosted and subset, and no font is added for a few small labels.\n- Third-party scripts load after the first interaction, and the trade-off is written down.\n- On Cloudflare Workers: static pages don't go through the big Worker, /_next/static is cached long term, the IMAGES binding is on, and there's no fs.\n\nFAQ\n\nDo I need a Worker in front on Vercel?\n\nNo. Vercel serves prerendered pages from its edge cache without starting the app, so the first-request start-up cost mostly doesn't apply to static pages. The UI, code, assets and third-party sections apply the same way.\n\nShould we chase the PageSpeed score?\n\nWe don't promise a score for any website. As the image at the top shows, the same build can score 68 or 95. The score also depends on content added later, the hosting and third-party scripts. A more useful goal is an LCP element that shows early, a page that doesn't shift, and pages that don't load code they don't use. Once a site has enough traffic, CrUX data is the number to look at first. PageSpeed Insights & Core Web Vitals (/en/insights/pagespeed) walks through three real cases where the lab score and real-user data disagree.\n\nDo phones lose the effects?\n\nThe content is the same on every device. Effects that need a cursor (water reacting to the mouse, the animated cursor) are desktop only. Heavy effects (the water canvas, the bending project cards) have lighter versions or become a plain layout on phones.\n\n1. OpenNext: Cloudflare\n2. web.dev: Largest Contentful Paint\n3. Next.js: Link component, prefetch\n4. fontTools: pyftsubset\n5. Cloudflare Workers: Service bindings\n6. Cloudflare Workers: Static assets headers\n7. Google: About PageSpeed Insights"},{"kind":"insight","locale":"en","slug":"lottie-animation","title":"Lottie animation","shortTitle":null,"excerpt":"What is Lottie? It packs an animation into a light, sharp file you can use on a website. Learn how to recolour it to your brand, how to use it on WordPress and Next.js, and try it out right in the article.","categories":["Animation","Design"],"tech":[{"id":"lottie","label":"Lottie"},{"id":"wordpress","label":"WordPress"},{"id":"gutenberg","label":"Gutenberg"},{"id":"nextjs","label":"Next.js"}],"date":"2026-10-01","updated":null,"dateModified":"2026-10-01","url":"https://perxel.com/en/insights/lottie-animation","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Lottie packs an animation into a file you can share and use across platforms, the way you would share an image or a video file. This article covers what Lottie is, where it fits on a website and how to use it.\n\nMost of the illustrations on the Perxel website use artwork from various authors on LottieFiles, recoloured to match Perxel's brand. Perxel also uses Lottie on client websites, both WordPress and Next.js.\n\nWhat is Lottie\n\nLottie is an animation format developed by Airbnb. A designer makes the animation in After Effects and exports a Lottie file, or picks a ready-made one from the LottieFiles library. The file describes vector shapes and how they move, and the browser reads the file and redraws the animation.\n\nBecause it is vector, the animation renders sharp at any screen size. Because the file holds data rather than fixed pixels, you can still change colours and control speed and the timeline after export, much like a video, but lighter and sharper.\n\nFor example, the rocket Lottie on the Perxel homepage is only 26 KB. The JSON inside is 283 KB, and the compressed .lottie format brings it to under a tenth of that. When handing over, designers should send the .lottie file instead of .json.\n\nChoosing a Lottie file for a design\n\nBefore choosing a Lottie file for a design, a designer should check a few things:\n\n- Choose flat vector shapes. Some Lottie files embed PNG images. They are heavier, blur when enlarged and are hard to recolour. Of the 22 Lottie files on the Perxel website, only 1 is like that.\n- Solid colours are easier to change than gradients. Solid colours can be edited right in the file. Gradients often mean going back to After Effects or the LottieFiles editor.\n- Check what background the animation will sit on. An illustration that looks good on white can disappear on a brand-colour background. The Perxel website has a separate light version for its blue cards.\n- For a continuous loop, the first and last frames must match. Otherwise every loop has a visible jump.\n\nRecolouring to match the brand\n\nFiles from LottieFiles may be drawn by many authors, so each has its own set of colours. Side by side they look inconsistent. Perxel recolours every file to one shared palette: the brand's blue range, warm neutrals and at most one orange accent, like a rocket's flame or a ray of light.\n\nThe palette is split by role: colours for outlines, for the light and dark sides of blue objects, for backgrounds and for accents. Each colour in the original file is mapped to a role, then the colour value is replaced right in the file. There's no need to reopen After Effects, and nearly 20 illustrations from different authors on Perxel now share one palette.\n\nIf a project has its own illustration palette, designers should send it with the handoff so the developer recolours correctly from the start instead of guessing.\n\nTry it yourself\n\nA Lottie file can be controlled freely like a video clip, and the special part is that you can change its colours. Try the controls below.\n\nPlayback modes:\n\n- Play on scroll: the animation plays when it appears on screen and stops when you scroll past. Good for illustrations in sections.\n- Play on hover: plays only when the pointer is over it. Good for cards and icons. Phones have no hover, so Perxel uses hover on desktop and switches to play on scroll on mobile.\n- Play once: plays through and stops on the last frame. Good for moments like a form sent successfully.\n\nAlso:\n\n- Speed: can be adjusted freely.\n- Background colour: change it to suit where it is used.\n\nWhen a design has animation, note the playback mode (scroll or hover) next to the frame in Figma. The developer won't have to guess, and it is part of keeping a clean Figma handoff (/en/insights/figma-handoff).\n\nWhat visitors experience\n\nYou may wonder whether adding animation slows the site down. This is how Perxel uses Lottie on its websites:\n\n- Light files, so page weight doesn't grow. The Lottie files on this site range from 2 KB to about 110 KB, smaller than an ordinary PNG.\n- Nothing plays off screen. Animation outside the viewport pauses, so the device doesn't spend resources rendering what nobody can see.\n- No layout jump on load (CLS). The layout space is reserved before the file finishes loading, so the content below isn't pushed down.\n- Respecting the viewer's settings. People who have turned on reduce motion in their operating system see a single still frame.\n\nTo render Lottie, the browser also needs to load a library of about 500 KB. Perxel hosts this library itself and loads it only on pages that have Lottie. The browser downloads it once and reuses it on later pages.\n\nLottie on WordPress\n\nA WordPress site can use Lottie by installing the official LottieFiles plugin, which adds a Lottie block to the Gutenberg editor.\n\nThe block offers several ways to add an animation: search the LottieFiles library, drag and drop a file, paste a link or pick a file already in the Media Library. In the block's sidebar, the admin can set speed, how it plays (on load, on click, on scroll or on hover), whether it loops or plays once, reverse playback, size per screen and background colour.\n\nWhen not to use Lottie\n\nIf the motion is very long, or its content can't be drawn as vector shapes (textures or 3D, for example), a Lottie file is no longer light and video is the better choice.\n\nIf the animation is the main visual, appears first on the page or takes a lot of space, a still image is better for loading speed. Even if a Lottie file is lighter than some images, it always waits for JS to load before it can render. The Perxel homepage has a Lottie on the first screen too, but only as a decorative detail beside the headline.\n\nIf the effect is simple, like a button changing colour, fading or sliding in, CSS can do it and no Lottie file is needed.\n\nIf your project needs animation so the page isn't too static and feels more lively, see Perxel's Web animation (/en/services/web-animation) service.\n\n1. Lottie, Airbnb\n2. LottieFiles plugin, WordPress.org\n3. How to add Lottie animations to WordPress, LottieFiles\n4. dotlottie-web, LottieFiles"},{"kind":"insight","locale":"en","slug":"tinacms","title":"TinaCMS & Next.js","shortTitle":null,"excerpt":"A look at TinaCMS, a Git-backed headless CMS with click-to-edit on the Next.js interface, no language limits and low long-term running cost.","categories":["CMS","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"}],"date":"2026-09-15","updated":null,"dateModified":"2026-09-15","url":"https://perxel.com/en/insights/tinacms","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Related service","title":"Next.js & Headless CMS websites","href":"/en/services/nextjs"}],"body":"Most SaaS headless CMSs keep data in their own cloud database and charge on a recurring basis by number of editors, storage or number of languages. TinaCMS takes a different route: an open-source headless CMS built on Git, integrated straight into the code of a Next.js project.\n\nAt Perxel, TinaCMS is one of the core solutions researched and used in practice for a visual editing experience and low long-term cost. To be clear, TinaCMS is first of all a visual editor. The CMS features around it (content modelling, administration, rollback) are basic and not as deep as a commercial headless CMS such as Prismic.\n\nClick-to-edit on the live interface\n\nThe biggest difference between TinaCMS and most traditional headless CMSs is visual editing. Instead of typing into a form in a separate admin and opening a preview tab, the admin logs into TinaCMS and edits directly on the website itself.\n\nYou click a heading, paragraph or image on the page to edit it, and every change shows on screen immediately. It feels close to no-code tools like Webflow or Framer, while keeping the performance tuning and code-level flexibility of Next.js.\n\nEditing directly on the live interface, shown on the Atlas Robotics project.\n\nGit-backed: the data lives in the project code\n\nUnlike headless CMSs that store data in a third-party SQL or NoSQL database, TinaCMS is Git-backed. Each time a user presses Publish, the system makes a Git commit that saves the change as a JSON or Markdown file in the project's GitHub repository.\n\nBecause content lives with the code, the site can be statically generated (SSG) and deployed to an edge network such as Cloudflare Workers or Vercel with no database or separate media hosting to maintain. The business also owns the full history of content changes through Git history.\n\nEach page is its own Markdown file, managed directly in the project repository.\n\nCore advantages\n\n- No limit on languages. Because data is stored in the repository, TinaCMS lets you configure 3, 5 or more languages with no per-locale plan upgrade.\n- No bandwidth charges. Content is served from the site's own statically built output, not through a separate CMS CDN that bills per download.\n- Minimal running cost. TinaCMS's free plan includes 2 editor accounts, enough for most business sites run by 1 or 2 content owners. When the team grows, the paid Team plan (about $24 a month) raises that to 3 editor accounts.\n\nContent for each language sits in its own folder: en, vi, zh, shown on the Atlas Robotics project.\n\nA plain verdict: 8/10 for marketing websites\n\nAfter years of using WordPress as its main CMS, Perxel rates TinaCMS 8/10 for marketing websites. The Git-backed architecture is a big plus, but the two points below are real limits to know before you commit.\n\n- Limited admin extensibility (-1). Perxel tried building its own dashboard inside TinaCMS to track SEO and multi-language data. It worked locally but not in production. Documentation for advanced customisation is thin, and the difficulty of overriding the admin UI or adding custom pages makes it less friendly to non-technical users.\n- Asset caching isn't optimal (-1). Media served from assets.tina.io doesn't have a suitable cache setup right now. That doesn't wreck the PageSpeed score, but it doesn't lift it either: on Atlas Robotics the Performance score stays at an acceptable level, below what Prismic reaches. Perxel hasn't found a complete fix, and it isn't clear whether this is specific to the free plan.\n\nPageSpeed Insights, mobile.\n\nPageSpeed Insights, desktop.\n\nThe setup challenge and Perxel's answer\n\nThe freedom and long-term savings of TinaCMS come with a much longer initial setup than an ordinary SaaS CMS. The developer has to define the whole content schema, connect GitHub to Next.js and tune the components so click-to-edit runs smoothly without slowing page loads.\n\nSeeing that barrier, Perxel invested a research and development phase to package a standard starter for Next.js with TinaCMS. That know-how is backed by the Certified Developer badge from TinaCMS (/en/insights/certified-tinacms-developer). With the starter already tuned, setup time isn't charged to the client's budget.\n\nWhen to choose TinaCMS\n\n- When the content team values click-to-edit directly on the page.\n- When the site needs 3 or more languages and you want to avoid per-locale enterprise plan fees.\n- When the business wants to cut server costs and monthly CMS fees as far as possible.\n\nClosing\n\nPerxel first met TinaCMS and shipped it in just 3 days on the Growtrics project (/en/works/growtrics), a creative website with complex GSAP animation. The client, a technical team, hadn't asked for a CMS at all, but Perxel added one anyway and they were glad to be able to manage content themselves afterwards.\n\nFrom that project, Perxel built Atlas Robotics (/en/products/atlas-robotics) to test the real limits of the stack: three languages, several gigabytes of images and video, and a live demo at atlas-robotics.perxel.com. The site runs steadily, with a PageSpeed score at an acceptable level as noted above, though it doesn't beat Prismic on the same measure.\n\nTinaCMS gives the marketing websites Perxel builds an alternative to WordPress with low infrastructure cost.\n\nRead more about Perxel's Next.js & Headless CMS website service (/en/services/nextjs), or the TinaCMS vs Prismic comparison (/en/insights/tinacms-vs-prismic) if you are still deciding between the two.\n\n1. TinaCMS\n2. TinaCMS: Pricing"},{"kind":"insight","locale":"en","slug":"prismic-headless-cms","title":"Prismic & Next.js","shortTitle":null,"excerpt":"A look at Prismic, a commercial headless CMS for Next.js with Slice Machine, automatic revalidation through webhooks, a friendly editor and a strong developer ecosystem.","categories":["CMS","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"prismic","label":"Prismic"}],"date":"2026-09-15","updated":null,"dateModified":"2026-09-15","url":"https://perxel.com/en/insights/prismic-headless-cms","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Related service","title":"Next.js & Headless CMS websites","href":"/en/services/nextjs"}],"body":"Next.js with Prismic is a popular choice for modern business and marketing websites. Next.js handles performance, SEO and the build architecture, and Prismic handles content, so a marketing team can build pages without depending on a software engineer.\n\nWhat is Prismic?\n\nPrismic is a SaaS headless CMS designed for building and managing interface sections as a page builder made of Slices. Unlike heavy traditional CMSs, it separates the content layer completely from the Next.js presentation layer. It is a full-featured headless CMS, unlike solutions such as TinaCMS that focus mainly on the visual editing experience.\n\nPrismic's dashboard is modern and friendly even to admins with no technical background. Editors check content in a separate preview pane next to the editor (side-by-side preview) before publishing, instead of editing directly on the page.\n\nPrismic's page builder, shown on the Foldables project.\n\nDeveloper experience: Slice Machine, CLI and webhooks\n\nTechnically, Prismic has a mature developer toolset.\n\n- Slice Machine. Lets developers package Next.js interface components as reusable Slices. The marketing team arranges the Slices to build new landing pages without breaking the standard layout.\n- Automatic revalidation through webhooks. On every publish, Prismic fires a webhook to Next.js that refreshes the cache almost instantly, with no full rebuild.\n- CLI and supporting ecosystem. A command-line tool automates project setup, backed by the documentation and support team of a large SaaS provider.\n\nLimits and cost model\n\nPrismic's free plan includes 1 editor account, 2 languages and 100 GB of bandwidth a month, with no overage allowed. That is enough for most company sites and ordinary marketing campaigns.\n\nWhen a business needs more editors or more languages, the paid Starter plan (about $10 a month) raises that to 3 editor accounts and 3 languages. Higher plans scale with the editors and locales needed.\n\nWhere it fits at Perxel\n\nPerxel finds Next.js with Prismic a good fit for businesses that want a stable headless CMS with an easy admin from day one and don't need more than 2 languages at the start. For projects that need to move quickly, Prismic shortens the time the client's team needs to get used to the system.\n\nThe setup has been tested on the Foldables (/en/products/foldables) test project, with a live demo at foldables.perxel.com. PageSpeed Insights gives 92 on both mobile and desktop, higher than the comparable project built with TinaCMS.\n\nPageSpeed Insights, mobile.\n\nPageSpeed Insights, desktop.\n\nRead more about the Next.js & Headless CMS website service (/en/services/nextjs), or the TinaCMS vs Prismic comparison (/en/insights/tinacms-vs-prismic) to choose the right fit.\n\n1. Prismic\n2. Prismic: Pricing"},{"kind":"insight","locale":"en","slug":"tinacms-vs-prismic","title":"TinaCMS vs Prismic","shortTitle":null,"excerpt":"The strengths and weaknesses of TinaCMS (click-to-edit, Git-backed) and Prismic (modern editor, agentic web platform), to help you choose the right CMS for a Next.js website.","categories":["CMS","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"tinacms","label":"TinaCMS"},{"id":"prismic","label":"Prismic"}],"date":"2026-09-15","updated":null,"dateModified":"2026-09-15","url":"https://perxel.com/en/insights/tinacms-vs-prismic","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Related service","title":"Next.js & Headless CMS websites","href":"/en/services/nextjs"}],"body":"On a Next.js website, the choice of headless CMS affects the marketing team's day-to-day work and the long-term running cost. TinaCMS and Prismic are the two options in Perxel's standard toolkit, and they stand for two different philosophies. This article looks at the strengths and weaknesses of each in plain terms.\n\nQuick comparison\n\nThe editing experience\n\nTinaCMS stands out for previewing and editing content directly on the website's own interface (click-to-edit). The admin clicks a paragraph or image on the page to edit it, with no separate form interface to learn.\n\nTinaCMS is a visual editor first, not a full-featured CMS. The dashboard around it (page lists, collection management) is fairly basic and less refined than Prismic's page builder. That doesn't stop clients from running the site themselves: after Perxel hands it over, the client's team can edit content without a developer, a standard Perxel tunes for on every TinaCMS project.\n\nTinaCMS click-to-edit, shown on the Atlas Robotics project.\n\nPrismic doesn't support clicking directly on the page. Instead it gives you a separate preview pane next to the editor (side-by-side preview) inside the admin. They are two separate areas, but Prismic's admin is modern and easy for non-technical users from the first session.\n\nPrismic's page builder, shown on the Foldables project.\n\nLimits and running cost\n\nPrismic runs as a commercial SaaS. The free plan includes 1 editor account and 2 languages, with 100 GB of bandwidth a month and no overage allowed. Asset storage (images, video) has no size cap. When you need more, the Starter plan (about $10 a month) raises that to 3 editor accounts and 3 languages.\n\nTinaCMS is Git-backed and keeps data in the project's own repository. The free plan includes 2 editor accounts, no limit on languages and no charge for access bandwidth. Each file uploaded through Tina Cloud is capped at 100 MB, but with repo-based media (files stored in the repo instead of Tina Cloud), the real capacity depends on your Git host, not on a TinaCMS limit. When the editing team grows, the Team plan (about $24 a month) raises that to 3 editor accounts.\n\nBackup, rollback and stability\n\nThe two tools handle backup and restore in completely different ways. TinaCMS has no \"go back to the old version\" button in the editor. Restoring a previously published version of content takes a developer working in the code, which is a clear weakness compared with Prismic. Ordinary edits (typos, swapping an image, updating a price) are still done by the client without a developer. Only restoring an older version needs help.\n\nPrismic has a history panel in each document's editor, showing the full edit history with a diff view (additions and removals highlighted) and letting you restore any version in one click. It is on every plan, including the free one, and needs no Git.\n\nOn stability, TinaCMS is still a fairly new tool with a much smaller community and documentation than Prismic. It works well for real needs, but it isn't as mature or stable as Prismic, a SaaS platform that has run for years with a large product team behind it.\n\nDeveloper tooling and ecosystem\n\nPrismic has a large product team and rich documentation. It revalidates data automatically through webhooks, so static pages update almost instantly after publishing, and it adds a CLI and the Slice Machine model for packaging components as standard Slices.\n\nTinaCMS stores data as Markdown or JSON files in the Git repository. Technically that takes more up-front setup than Prismic: defining the schema, connecting GitHub and tuning so click-to-edit runs smoothly. For Perxel's clients, though, the difference no longer matters in practice: both starters, Atlas Robotics (/en/products/atlas-robotics) and Foldables (/en/products/foldables), are already proven, so a new project takes about the same time with either.\n\nAI support through MCP\n\nPrismic recently launched an official MCP server, which lets an AI assistant such as Claude or ChatGPT search, read and create content, upload assets and publish straight from a conversation, instead of working by hand in the dashboard. It is a clear move toward non-technical users: just talk to the AI to update the website.\n\nTinaCMS has no equivalent MCP server. But because TinaCMS content is already Markdown or JSON files in the code, it suits AI coding agents working directly on the codebase (such as Claude Code), an approach that leans toward technical teams more than general users.\n\nWhich one for which project\n\nFrom hands-on experience, Perxel suggests choosing by how the site will be run:\n\n- Choose Prismic when the site needs 1 or 2 languages, 1 person editing, and you want a professional, stable editor that is ready from the start, including working through an AI assistant.\n- Choose TinaCMS when the site needs 3 or more languages, more than 2 people editing, or you value click-to-edit and low long-term running cost, and accept a more basic dashboard and a smaller support community.\n\nClosing\n\nNo CMS is perfect for every project, only the one that best fits how the business will run and what it can spend. Perxel has tested both on test projects: Atlas Robotics (/en/products/atlas-robotics) with TinaCMS and Foldables (/en/products/foldables) with Prismic, both tested and ready to demo.\n\nRead more about the Next.js website service (/en/services/nextjs), or each solution on its own: TinaCMS & Next.js (/en/insights/tinacms) and Prismic & Next.js (/en/insights/prismic-headless-cms).\n\n1. TinaCMS\n2. TinaCMS: Pricing\n3. TinaCMS: Repo-Based Media\n4. Prismic\n5. Prismic: Pricing\n6. Prismic: Versioning and Restoring a Document\n7. Prismic: MCP Server"},{"kind":"insight","locale":"en","slug":"certified-tinacms-developer","title":"Certified Developer by TinaCMS","shortTitle":null,"excerpt":"Perxel has received the Certified Developer badge from TinaCMS, a step in standardising the Next.js and TinaCMS stack through the Atlas Robotics project.","categories":["CMS","Development"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"}],"date":"2026-09-14","updated":null,"dateModified":"2026-09-14","url":"https://perxel.com/en/insights/certified-tinacms-developer","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Today Perxel marks a new technical milestone: Phúc Bùi, the lead engineer at Perxel, has received the Certified Developer badge from the TinaCMS team after a review that took just over a week.\n\nThe confirmation email from Credly.\n\nThe badge is part of the official TinaCMS Certified Developer programme. After building a website with TinaCMS and TinaCloud, the applicant emails the TinaCMS team answers about the project setup (Client ID, pull request workflow, branch preview configuration) and how they handle a few real failure cases. The team reviews them and issues the badge through Credly.\n\nIt is a personal credential, and it also reflects how Perxel works: every technology that goes into a service is tested on real projects, and checked for performance before it reaches a client.\n\nIt started with a real need: a 3-day trial on Growtrics\n\nTinaCMS first entered Perxel's workflow on the Growtrics project (/en/works/growtrics), a creative marketing website for an EdTech startup in Singapore.\n\nThe site was handed straight to the client's in-house engineers, so the project didn't call for a heavy content management system. Perxel chose Next.js (/en/services/nextjs) to build the interface quickly and keep real-world loading performance high.\n\nNear handover there was time to spare, so Perxel tried adding a lean headless CMS that works naturally with Next.js without growing the codebase. The thinking was simple: even though the client could manage the code themselves, a visual editor would make the finished product more polished and easier to run over time.\n\nPerxel read the docs, integrated TinaCMS and handed over the product in just 3 days. That combination opened a new path for later marketing websites.\n\nStandardising the Next.js + TinaCMS stack with the Atlas Robotics test project\n\nNext.js with TinaCMS looked like a good fit for marketing sites and campaign landing pages on a moderate budget: live preview for editors, with monthly running costs kept to a minimum. Perxel dug deeper to make the stack part of its standard process.\n\nAtlas Robotics (/en/products/atlas-robotics) was built as a test project to check the model at a larger scale. With it, Perxel tried handling gigabytes of media, setting up a three-language site (English, Vietnamese, Chinese) and deploying on the Cloudflare Workers edge network (through OpenNext), with no dedicated server or database to pay for at this scale.\n\nWhat this means for businesses and creative agencies\n\nNext.js with TinaCMS balances performance, security and running cost for small and mid-size projects:\n\n- Fast loading and a smaller attack surface. The site is compiled to static pages, which keeps response times low and reduces the attack surface (no server code or database exposed on each request).\n- Minimal running cost. Content is stored as Git-backed files in the project repository, so there is no expensive hosting or monthly subscription to carry.\n- An editor that is just enough. The TinaCMS editor focuses on the content that needs editing, without clutter.\n\nClosing\n\nThe TinaCMS Certified Developer badge reflects Perxel's technical delivery and the care it puts into its work. To see how the stack is built and where it fits, read the Next.js & Headless CMS website service (/en/services/nextjs). Perxel will keep working alongside designers and brands to turn design ideas into finished, optimised websites that are easy to run for years.\n\n1. TinaCMS Certified Developer badge (Credly)\n2. TinaCMS Certifications"},{"kind":"insight","locale":"en","slug":"nectarblocks","title":"Meet NectarBlocks","shortTitle":null,"excerpt":"Perxel has used NectarBlocks across several real WordPress custom theme projects. This is a plain review of how it is actually used when building, not a feature tour.","categories":["WordPress","Development"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"gutenberg","label":"Gutenberg"},{"id":"nectarblocks","label":"NectarBlocks"},{"id":"pagespeed","label":"PageSpeed Insights"}],"date":"2026-09-12","updated":null,"dateModified":"2026-09-12","url":"https://perxel.com/en/insights/nectarblocks","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"In web development, the choice of page builder directly affects performance and the long-term editing experience. For a long time, classic page builders like WPBakery and Elementor were the common choice. They work as a separate system laid over WordPress's core structure, which adds code weight and slows real loading speed.\n\nGutenberg, WordPress's default editor, changed that. To improve the editing experience for clients, Perxel moved to NectarBlocks on custom theme projects. This article is Perxel's review after using it, not a feature list copied from the developer's homepage.\n\nAn added layer, not a separate system\n\nNectarBlocks isn't a standalone page builder that changes the nature of the system. It works as an extra layer that extends Gutenberg core directly. That is a real technical assurance: site owners keep using the default Gutenberg blocks alongside it, with much less risk of being locked into an unfamiliar page builder or breaking when WordPress updates.\n\nThe editing experience in practice\n\nThe core idea of NectarBlocks is to build layouts and control display properties right inside the WordPress admin. Instead of staying at simple content blocks, it reaches into CSS properties in the editor: rows, columns, responsive settings per device, hover effects and animation.\n\nThe NectarBlocks editor inside WordPress admin: layer tree on the left, live canvas in the middle, style and spacing panel on the right.\n\nYou can think of it as something like Webflow on WordPress. Site owners control spacing (margin, padding), alignment (flexbox, grid) and effects right in the editor, and the code stays lean.\n\nFrom ready-made blocks to project-specific code\n\nBeyond rows, columns, text and images, NectarBlocks ships a fairly full set of blocks: Post Grid for lists of posts, Carousel and Marquee for horizontal content, Accordion, Testimonial, Icon, Video Lightbox and a separate set for WooCommerce. It also supports scroll animation, global styles for colours and fonts across the site, and dynamic data through Advanced Custom Fields (ACF).\n\nOn Perxel's custom theme (/en/services/wordpress-custom-theme) projects, most of these blocks aren't used directly. A real custom theme means writing bespoke code from the Figma design so the brand's look is its own, so Perxel doesn't use NectarBlocks' prebuilt designs.\n\nPerxel uses only the basic layout blocks (rows, columns, text, images) to shape the page skeleton in the admin. Everything specific to the design, such as animation, testimonials or product layouts, is written by hand so it matches the original drawing, instead of using a page builder's ready-made version.\n\nSEO controls in the image block\n\nOne small but useful detail of NectarBlocks is the image block. Alt text, image ratio and link attributes (rel, open in a new tab) all sit in the block's settings panel, instead of a separate settings screen or a field that is easy to miss.\n\nThe image block panel: Alt Text, Resolution, Image Ratio and link attributes are all in the editing area.\n\nAlt text is one of the most basic SEO items and the one editors most often skip when they publish posts themselves. Putting the field next to the image, rather than hiding it in a separate tab, makes it more likely that editors fill it in.\n\nReal-world performance\n\nBecause NectarBlocks is an added layer on Gutenberg core, not a system of its own, the code it generates is fairly lean. The PageSpeed Insights screenshot below was taken on nectarblocks.com itself, not on a site Perxel delivered, but it shows the technology underneath doesn't bring a significant performance cost.\n\nPageSpeed Insights measured on the nectarblocks.com homepage.\n\nThe PageSpeed score on any real project also depends on the content, images and hosting plan the client uses after handover. So this is an illustration of the underlying technology, not a score for every website Perxel delivers.\n\nLicence model and continuity\n\nNectarBlocks is a paid page builder, sold as an annual or lifetime licence, not free like core Gutenberg. On Perxel projects the licence cost is part of the initial development cost, so clients don't pay for or renew it themselves.\n\nThe licence also keeps things running over the long term:\n\n- Design features keep working. Even after a licence expires, site owners can still edit text and images, change layouts or add pages using the existing blocks, without limits.\n- What an expired licence limits. The system stops receiving the latest automatic updates and can't reach the developer's cloud template library.\n\nFor sites delivered by Perxel, this barely affects day-to-day running, because the whole interface is written as custom code from the Figma design and doesn't depend on the sample template library.\n\nThe editing experience for site owners\n\n- Visual input. Site owners can easily change text, update images or add content in a visual editor without knowing code.\n- The layout stays intact. The display logic and the specific design style are written by Perxel in the theme's own code, so everyday content updates don't accidentally break the overall layout.\n\nIn short\n\nNectarBlocks is an effective way to extend default Gutenberg without giving up the lightness and loading performance of WordPress core. For Perxel, most of its value is in the basic layout frame and the editing experience for clients, while every real design detail is still written by a developer to stay close to the original Figma idea.\n\n1. NectarBlocks\n2. NectarBlocks: Meet NectarBlocks\n3. WordPress: Block editor (Gutenberg)"},{"kind":"insight","locale":"en","slug":"cross-browser-cross-device","title":"Cross-device & cross-browser testing","shortTitle":null,"excerpt":"A clear testing scope for browsers, devices and screen sizes keeps agencies and clients from misreading how compatible a website is, and lets the development team spend effort on the environments that matter.","categories":["Design","Development"],"tech":[{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"safari","label":"Safari"}],"date":"2026-08-14","updated":null,"dateModified":"2026-08-14","url":"https://perxel.com/en/insights/cross-browser-cross-device","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"\"The website should look right on every device and browser\" quickly turns into an unrealistic, open-ended promise if the testing scope isn't defined at the start of a project. After handover, one small display bug on a client's outdated device is enough to cause a misunderstanding nobody wanted.\n\nTo put the effort where it counts, Perxel agrees the testing scope up front, based on real data and current technology.\n\nBrowser scope\n\nPerxel tests and optimises for the latest versions of the common browsers at the time of development: Google Chrome, Safari and Microsoft Edge.\n\nFocusing on the latest versions lets the site use modern web technology, perform better and avoid known security holes.\n\nTo keep this grounded, Perxel uses market-share data from StatCounter for the project's target market and picks the three most common versions of each browser for extended testing. For a Vietnam audience, for example, Chrome leads and Safari comes second.\n\nDevice and screen-size scope\n\nA website can't look identical on every device on the market. Perxel's testing covers the most common screen sizes for each project's audience.\n\n- On desktop for a Vietnam audience, usage is spread fairly evenly across 1920x1080, 1366x768 and 1280x800.\n- On mobile, the most common size is around 414x896.\n\nIf your project already has real user data from Google Analytics 4, Perxel encourages you to share it. The Tech Overview report in GA4 shows exactly which browsers and screen resolutions your visitors use most, which makes the testing as useful as it can be.\n\nThe reviewer's own devices\n\nMarket data can't predict one very important group of devices: the ones used by the people who review and approve the project.\n\nInside a company, the marketing team may use recent devices while the leadership signing off may use a machine that is several years old, or review the site on a large screen in a meeting room. A small bug that shows up only on the approver's own device on sign-off day can colour their whole impression of the work.\n\nThat's why Perxel asks agencies to help collect the devices the client's reviewers will actually use.\n\nAll you need is for the reviewer to open whatismybrowser.com on their device and send a screenshot of the browser details. With the exact browser version and operating system, Perxel can set up a matching test environment and fix compatibility issues before the review meeting.\n\nIn short\n\nPerxel's cross-device testing doesn't promise a flawless site on every device ever made.\n\nInstead, Perxel agrees a sensible testing scope with the agency, based on real user data and current technology. The designer then knows the limits of how the site will display, the developer puts the most effort into the environments that matter, and the delivered site looks its best in your client's hands.\n\n1. StatCounter Global Stats\n2. whatismybrowser.com"},{"kind":"insight","locale":"en","slug":"figma-handoff","title":"Figma handoff","shortTitle":null,"excerpt":"A complete Figma file is a solid base for development. Between design and a production website, a good exchange between designer and developer keeps the decisions on responsive behaviour, typography, interaction and animation true to the design intent.","categories":["Design"],"tech":[{"id":"figma","label":"Figma"}],"date":"2026-08-14","updated":null,"dateModified":"2026-08-14","url":"https://perxel.com/en/insights/figma-handoff","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"When a Figma design becomes a finished website in the browser, Perxel's first goal is to keep the designer's creative intent and visual language intact. Besides a clear Figma file, that takes designer and developer agreeing on how to think about responsive behaviour, typography, web interaction and the structure of the design.\n\nFigma is the reference, the browser is reality\n\nFigma is a static environment where the designer controls the exact canvas size and the position of every element. A real website is dynamic. It runs on many screen sizes, is shaped by each operating system's font rendering and by differences between browsers, and is bound by the limits of HTML and CSS.\n\nFigma is the authoritative reference. At the screen size the agency designed for, Perxel aims for the site to match the drawing. More importantly, the site also has to behave naturally when the window is resized or the real content arrives. A developer doesn't just read static pixel values from Figma but needs to understand the layout logic and the intent behind it.\n\nBringing in the developer at the right time\n\nPerxel doesn't treat early developer involvement in every creative decision as a requirement, because every creative agency has its own process. Figma recommends involving developers early, and that approach helps a lot when the design has many interactions or demanding technical requirements. But technical advice at the right moment is what adds the most value, so surprises don't appear after the client has approved the design.\n\nKnowing a technical limit, or how complex an animation really is, before the client signs off lets the agency decide on its own terms: keep it, simplify part of it or adjust the project scope. Perxel is available for technical advice whenever a designer or agency needs it.\n\nDesign, responsive behaviour and production\n\nNatural responsive behaviour\n\nResponsive doesn't mean the designer has to design every breakpoint. On many projects the agency delivers only the desktop design and Perxel builds the responsive version for mobile.\n\nRather than just scaling things down or hiding elements, Perxel reworks the layout: it changes the grid, adjusts typographic spacing and tunes touch targets, so the experience and the hierarchy of the original design carry over.\n\nAligning on typography\n\nTypography affects the vertical rhythm of the whole page. A small difference in how Chrome, Safari, macOS or Windows render a font can move a heading onto another line and change the height of a block.\n\nSo Perxel checks fonts from the first days of development. If the design uses a font outside Google Fonts, the agency needs to provide .woff or .woff2 files so it displays properly on the web.\n\nA well-organised design system\n\nA Figma file organised with Components, Styles and Variables lets a developer quickly tell which patterns are shared and which are deliberate exceptions. That speeds up the build and keeps the site consistent as it grows to more pages.\n\nA clear source of truth\n\nTo spare the developer from guessing which frame is the final one among many experiments, the designer only has to organise the file clearly. A separate page for the final design, clear naming or Figma's \"Ready for development\" status gives both sides a shared language.\n\nDesign with real content\n\nA real website runs on live content, not short placeholder text. Real content can be two or three times longer, which changes the height of cards and breaks the balance of a layout. Using reasonably complete content in Figma helps the site avoid unexpected display problems once it is live.\n\nTelling a story with web animation\n\nWeb animation is one of Perxel's core strengths, but a good site needs one consistent motion story across the page, not a patchwork of separate effects.\n\nMotion needs rhythm, pace and a clear link between sections. An important section may need strong movement to draw attention, while the sections after it should stay quieter so people can focus on the content. Perxel's technical advice tells the designer what is feasible, how it affects loading performance and what works best on mobile, before anything is built.\n\n1. Figma: Design handoff\n2. Figma: A guide to developer handoff"},{"kind":"insight","locale":"en","slug":"no-code-vs-custom-development","title":"No-code or custom development","shortTitle":null,"excerpt":"No-code isn't always cheaper once you count the whole life of a website. Here is how an agency can weigh design complexity, page structure and lifespan before choosing a technology.","categories":["Development"],"tech":[{"id":"webflow","label":"Webflow"},{"id":"framer","label":"Framer"}],"date":"2026-08-13","updated":"2026-10-10","dateModified":"2026-10-10","url":"https://perxel.com/en/insights/no-code-vs-custom-development","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Related service","title":"Next.js & Headless CMS websites","href":"/en/services/nextjs"}],"body":"For the right kind of project and a team that already knows the platform, Webflow or Framer can get a creative agency's website live very quickly. But when a site has a complex design, many pages, lots of interactions or keeps growing, running it on no-code still takes nearly the same level of skill, and can be just as involved as writing code.\n\nSo the practical question isn't which system is better. It's which way of building and running fits this project.\n\nWhen is no-code a good choice?\n\nNo-code fits best when the site is fairly simple and your team already has experience with the platform they chose.\n\n- A small site with a standard design. A company site with a few standard pages or a portfolio rarely needs a complex codebase. If the design isn't unusual, a developer who knows Webflow or Framer well can build and hand over much faster than with custom code.\n- Short-lived landing pages, made all the time. A marketing agency may constantly need campaign pages, product launch pages or event pages. After handover, the agency's design or marketing team can create and edit them directly on the platform without going back to a developer.\n\nOne caveat: no-code is only simple when the team knows how to use it. Running a large Webflow or Framer site well still takes an understanding of responsive layout, component structure, design systems, CMS data modelling, SEO and more. Not writing code doesn't mean not needing technical knowledge.\n\nWhen does no-code start to cause problems?\n\nThe trouble rarely shows at the start. A 10-page site is easy to build in Webflow. At 50, 100 or 300 pages, how components, content and the design system are organised starts to decide whether the site stays easy to maintain.\n\nThe more custom the design, the harder the build\n\nA Figma file can be perfectly clear to a designer yet not map directly onto how a no-code platform works. The team then ends up wrestling with breakpoints, nested components, style overrides and a complicated CMS structure.\n\nCost grows with pages and CMS items\n\nBoth Webflow and Framer cap pages and CMS items on lower plans and charge more beyond the cap. Custom development doesn't charge per page. The cost sits mostly in building the architecture at the start, plus hosting and a headless CMS plan if the project uses one (those plans have their own limits too).\n\nPlan limits and prices change often. Check the Webflow and Framer pricing pages linked at the end of this post.\n\nMarketing sites live a long time\n\nA real marketing site usually starts at a few dozen pages, then grows to hundreds, adds languages and adds new interactions. At that point the architecture chosen at the start decides whether the site can keep growing.\n\nCustom development doesn't mean asking a developer to change every word\n\nA common worry with custom development is that after handover, every content change needs a developer. That's no longer true once the site is connected to a headless CMS like TinaCMS or Prismic (/en/insights/tinacms-vs-prismic).\n\nThe developer builds the content blocks to match the design. The marketing team then creates new pages, arranges blocks and edits content in a visual editor without touching code.\n\nArranging blocks and editing content in Prismic's page builder, shown on the Foldables project.\n\nThe difference is how much can be changed. On no-code, editors can change almost everything, layout included. With a headless CMS, each block only allows what was defined up front, so the design still holds after months of use.\n\nWhen to choose custom development\n\nCustom development fits when the site has to be built exactly to the design and the real requirements, instead of bending the design to fit a platform's limits.\n\n- When the design is the core value. If the agency sells creative direction and the site has to show every approved detail, the developer needs full control of the frontend. The platform shouldn't decide how your website looks.\n- When the interactions are complex. Scroll-based animation, custom transitions, interactive storytelling, WebGL and 3D all need direct control of the code to keep performance steady. The homepage of the Perxel website (/en/works/perxel-website) is one example: the water rising as you scroll, the whale and the paper plane are all drawn on canvas in code.\n- When the site will grow for years. A marketing site rarely stops at launch. New features, new languages, API integrations and SEO changes keep coming. Custom development gives deep control and room to upgrade over time without depending on a third party.\n\nThe whale on the Perxel homepage is drawn entirely in code on a canvas and swims as you scroll.\n\nAt a glance\n\nFive questions to answer before choosing\n\nThat number decides which no-code plan you need and how the CMS should be structured from the start.\n\nThe more unusual the design, the more time it takes on no-code.\n\nIf they only edit text, swap images and add pages from existing templates, a headless CMS is enough. If they need to build new layouts often, no-code is more flexible.\n\nThese needs usually come up after launch, so plan for them before choosing a platform.\n\nOn no-code, the site is tied to the platform. With custom development, the code is yours and another team can pick it up.\n\nIf most answers point to few pages, a standard design and a short life, no-code is a sensible choice. If the site will grow, the design is bespoke and it has to run for years, custom development costs less over time.\n\nIn short\n\nNo-code isn't always the cheaper choice when you count the full life of a website. Custom development costs more time and money up front, but gives deeper control over the interface, animation and loading speed. Which one to pick depends on the scale, design and lifespan of the project itself.\n\n1. Webflow Pricing\n2. Framer Pricing"},{"kind":"insight","locale":"en","slug":"pagespeed","title":"PageSpeed Insights & Core Web Vitals","shortTitle":null,"excerpt":"How to read a PageSpeed Insights report: how lab scores differ from real-user data (CrUX), what each Core Web Vital means, three real cases from sites we built, and how we optimise WordPress and Next.js sites.","categories":["Performance","Development"],"tech":[{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"wordpress","label":"WordPress"},{"id":"wpbakery","label":"WPBakery"},{"id":"gutenberg","label":"Gutenberg"},{"id":"nextjs","label":"Next.js"}],"date":"2026-08-08","updated":"2026-10-10","dateModified":"2026-10-10","url":"https://perxel.com/en/insights/pagespeed","visibility":"public","deliveredByPerxel":true,"related":[],"projects":["khatra","perxel-website"],"usedBy":[],"links":[],"body":"PageSpeed Insights is the most common way to judge a website's speed, and its score out of 100 is often treated as the final word. That number is only one simulated test. The same report has another part that gets less attention and is closer to what people actually experience: data from real Chrome users who visited the site.\n\nThis article explains how to read a PageSpeed report, what each metric means, and three real cases from sites Perxel built, one of which scores high thanks to a trick we describe openly here. The last part covers how we optimise WordPress and Next.js sites.\n\nA PageSpeed report has two parts\n\nThe top part, \"Discover what your real users are experiencing\", is field data from the Chrome User Experience Report (CrUX): real measurements from Chrome users who visited the page over the last 28 days, taken at the 75th percentile of visits. If the page doesn't have enough visits, PageSpeed shows data for the whole domain (Origin). If the domain doesn't either, it shows \"No Data\".\n\nThe lower part, \"Diagnose performance issues\", is lab data: Lighthouse loads the page once on an emulated low-end phone (a Moto G Power) over Slow 4G, as a first visit, and scores it. The Performance score out of 100 lives here.\n\nThe two parts answer different questions. Lab data tells you what's wrong under fixed conditions, which is useful for finding problems and comparing before and after a change. Field data tells you what real visitors went through. When a page has CrUX data, that's the number to look at first.\n\nWhat the metrics mean\n\nThe first three are the Core Web Vitals. A page passes when all three are good for 75% of visits.\n\n- LCP (Largest Contentful Paint): how long until the largest piece of content shows. Good is under 2.5 seconds. It's usually a banner image or a big headline. A slow LCP usually means the banner image loads late (lazy loaded, or waiting for a script to swap it in), or the headline waits on JavaScript or a font.\n- INP (Interaction to Next Paint): how quickly the page responds to input. Good is under 200 ms. It can only be measured from real users; in the lab, TBT (Total Blocking Time) is the closest stand-in. A slow INP usually means long JavaScript tasks on the main thread.\n- CLS (Cumulative Layout Shift): how much the page jumps while it loads. Good is under 0.1. Common causes are images without dimensions, elements that JavaScript moves after the page has shown, and animations that change size or position with width or top instead of transform.\n- FCP, TTFB and Speed Index are supporting metrics. FCP is when the first content appears (good is under 1.8 seconds). TTFB is the wait for the first byte from the server (good is under 0.8 seconds), mostly down to hosting and caching. Speed Index measures how quickly the screen fills with content.\n\nThree real cases\n\nThe three sites below were built by Perxel and measured on the same day, 10 October 2026. Each shows a different kind of gap between the lab score and real experience.\n\nKhatra Tile: a lab score of 73, Core Web Vitals passed for real users\n\nKhatra Tile (/en/works/khatra) is a WordPress site built with WPBakery that has been running for over 10 years. On mobile it scores only 73 in the lab, with an LCP of 4.7 seconds. Yet the domain's mobile CrUX data passes Core Web Vitals: LCP 2.2 seconds, INP 95 ms, CLS 0.02.\n\nKhatra Tile on mobile, 10 October 2026: the domain's real-user data passes Core Web Vitals, while the lab run scores 73.\n\nThe lab measures a first visit on a low-end phone over a slow network. Real visitors use all kinds of devices and networks, and some come back with the browser cache already warm. So a lab score can be harsher than reality: a 73 doesn't mean visitors are getting a slow site.\n\nKhatra's mobile version still has room to improve, since we haven't focused on mobile for it yet:\n\n- The banner image waits for a script. The WebP plugin runs in a mode that puts a placeholder in the HTML and swaps in the real image with JavaScript, so the LCP image waits for that script.\n- Too many images are marked as priority. Every banner slide, desktop and mobile copies alike, has fetchpriority=\"high\", so the first image shares bandwidth with about 10 others.\n- Real-user TTFB is 1.3 seconds on mobile. A cached page comes back in about 0.1 seconds and an uncached one in about 0.7 seconds (measured with curl on 10 October 2026). The rest is connection time on mobile networks.\n\nSundmd: a lab score of 99 that isn't the real experience yet\n\nSundmd is a new WordPress site built with NectarBlocks on Gutenberg. It scores 99 on mobile in the lab and has no CrUX data yet, because the site is new.\n\nSundmd on mobile, 10 October 2026: 99 in the lab, no real-user data yet.\n\nPart of that 99 comes from a trick. On the first visit of each session, Sundmd opens with an intro: the brand logo on a dark screen for about 4.5 seconds, then two curtains slide apart to reveal the page. The intro is part of the brand experience, so it stays. In the lab it costs a lot: the curtains shrink with width, which counts as a layout shift (CLS of about 0.18), and the main headline waits for the intro to finish (8.3 seconds of LCP render delay on its own).\n\nSo we check the request's user agent. When a request comes from Lighthouse, PageSpeed Insights, WebPageTest or headless Chrome, the server returns the page without the intro and with the headline's entrance animation switched off. Real visitors still see the intro as usual.\n\nThe testing-tool check on Sundmd (shortened). The last filter matters: if WP Rocket cached the intro-less page, real visitors would get it too.\n\nThe trick only changes the lab score, not what visitors experience. Once Sundmd has enough traffic, CrUX will include the intro, and we expect real-user CLS to land in \"needs improvement\" (around 0.18). The real fix is to animate the curtains with transform instead of width, which looks exactly the same:\n\n<!-- Before: the curtain shrinks its width, which Chrome counts as a layout shift -->\n<div class=\"absolute inset-y-0 right-0 w-[60vw] transition-[width] duration-700\nis-page-overlay-hidden:w-0\"></div>\n\n<!-- After: same look, the curtain scales down from its outer edge with transform -->\n<div class=\"absolute inset-y-0 right-0 w-[60vw] origin-right transition-transform duration-700\nis-page-overlay-hidden:scale-x-0\"></div>\n\nThat fix isn't applied yet. We'll update this article once Sundmd has CrUX data.\n\nOur own site: the same code, 68 and 95\n\nOur site runs on Next.js and has no CrUX data yet either. Two runs on the same build, a little over 13 hours apart, scored 68 and 95.\n\nThe same build of our homepage, two PageSpeed mobile runs: 68 and 95.\n\nOur site also has one thing that makes the lab look better than reality: Google Analytics loads on the visitor's first interaction, or after 15 seconds if there is none. The lab run never scrolls or touches the page and finishes before 15 seconds, so it never counts that script, while a real visitor loads it as soon as they scroll.\n\nHow to read the results\n\n- When there's CrUX data, read it first. As with Khatra, an average lab score can sit next to a real experience that passes.\n- When there's no CrUX data, take the median of several runs. A single run can be off by as much as 27 points, as on our site.\n- A very high lab score isn't proof of a good experience. Open the page in a normal browser and watch the first few seconds. CrUX has limits too: it only counts Chrome users who opted in to share data, and it only appears once a page has enough traffic.\n\nOptimising WordPress sites\n\nCSS and JavaScript\n\n- Tailwind CSS inside Gutenberg blocks. We have our own workflow for using Tailwind CSS in Gutenberg blocks, as on Sundmd. Classes are shared across blocks, so the final CSS file stays small.\n- JavaScript per component. On Khatra, each component registers its own JavaScript file and only enqueues it when that component renders, so a page that doesn't use a component never loads its script. For everyday interactions we write plain JavaScript instead of adding a library.\n- Vetted plugins only. Many plugins load their CSS and JavaScript on every page, including pages that don't use them. We keep a list of safe plugins (/en/insights/wordpress-plugin-list) and know which files each one needs.\n\nImages\n\n- Convert images to WebP on the server. Perxel Image Optimizer (/en/products/perxel-image-optimizer) creates WebP copies of the media library without sending images to an outside service.\n- Limit the number of image sizes. WordPress generates many sizes for every upload. We keep only the sizes that match the design's breakpoints, so srcset picks the right file without dozens of extra ones.\n- The LCP image loads right away, with high priority and known dimensions. On Khatra, the top banner image goes through its own function:\n\n// LCP image (top banner): load now, high priority, width/height so the page doesn't shift\nfunction px_output_lcp_optimized_image($id, $size = 'full', $class = '') {\n$meta = wp_get_attachment_metadata($id);\nreturn sprintf(\n'<img src=\"%s\" srcset=\"%s\" sizes=\"%s\" width=\"%d\" height=\"%d\" class=\"%s\" alt=\"%s\"\nfetchpriority=\"high\" loading=\"eager\" decoding=\"async\">',\nesc_url(wp_get_attachment_image_url($id, $size)),\nesc_attr(wp_get_attachment_image_srcset($id, $size)),\nesc_attr(wp_get_attachment_image_sizes($id, $size)),\n$meta['width'] ?? 0,\n$meta['height'] ?? 0,\nesc_attr($class),\nesc_attr(get_post_meta($id, '_wp_attachment_image_alt', true))\n);\n}\n\nUse it for exactly one image: the first banner slide, in the copy shown on that screen. As mentioned above, Khatra's homepage currently uses it for every slide, so the images compete for bandwidth.\n\nThird-party scripts\n\nGoogle Tag Manager, Facebook Pixel and chat widgets don't load when the page opens. On Khatra, GTM loads on the visitor's first interaction, or 3.5 seconds after the page has loaded:\n\n// Load GTM on the visitor's first interaction, or 3.5 seconds after the page has loaded\nlet loaded = false\nfunction loadGTM() {\nif (loaded) return\nloaded = true\nwindow.dataLayer = window.dataLayer || []\nwindow.dataLayer.push({'gtm.start': Date.now(), event: 'gtm.js'})\nconst script = document.createElement('script')\nscript.async = true\nscript.src = 'https://www.googletagmanager.com/gtm.js?id=' + GTM_ID\ndocument.head.appendChild(script)\n}\nwindow.addEventListener('load', () => setTimeout(loadGTM, 3500))\nfor (const event of ['scroll', 'mousemove', 'touchstart', 'keydown']) {\nwindow.addEventListener(event, loadGTM, {once: true, passive: true})\n}\n\nThe length of the wait is a choice: a short wait counts more short visits, a long one keeps the script further from page load. Khatra waits 3.5 seconds, our site 15.\n\nServer and caching\n\n- Cache on the server and in WordPress. We combine server caching (LiteSpeed on Khatra) with WP Rocket, so pages are served as static HTML without running PHP or querying the database. On Khatra a cached page comes back in about 0.1 seconds, an uncached one in about 0.7.\n- Clear the cache for the right pages when content changes. When an editor changes or adds content, the WP Rocket and server caches are cleared for that page and its related pages, so the new content shows straight away.\n- Runs on standard hosting. A lean custom codebase runs well on Nginx, Apache or LiteSpeed, with no need for a particular provider.\n\nOptimising Next.js sites\n\nNext.js needs a different approach from WordPress: controlling the JavaScript each page loads, prefetching, fonts and, on Cloudflare Workers, how the server answers static pages. We wrote up everything we did, with the numbers, in Next.js performance (/en/insights/nextjs-performance).\n\nTwo other Next.js projects of ours, Atlas Robotics (/en/products/atlas-robotics) and Foldables (/en/products/foldables), scored 84 and 92 on desktop in the runs below.\n\nPageSpeed Insights for Atlas Robotics, desktop.\n\nPageSpeed Insights for Foldables, desktop.\n\nFAQ\n\nThe lab score is low but real-user data passes. Should we still fix it?\n\nLook at what the lab points to before deciding. On Khatra, the banner waiting for a script and the many priority images are real problems, and fixing them helps visitors on slow phones and networks. But there's no rush because of the 73 itself, since most visitors already get an experience that passes.\n\nWhy don't we use the user-agent trick on every site?\n\nBecause it doesn't make the site faster for anyone. On Sundmd it only keeps the intro (a deliberate design choice) from hiding the other problems in the lab report. CrUX still records the full real experience, and the proper fix is to animate with transform.\n\nWhat should a new site with no CrUX data look at?\n\nTake the median of several lab runs, and read each metric rather than just the overall score. Search Console also shows a Core Web Vitals report once the site has enough data.\n\n1. Google PageSpeed Insights\n2. Google: About PageSpeed Insights\n3. web.dev: Web Vitals\n4. WP Rocket"},{"kind":"insight","locale":"en","slug":"wordpress-plugin-list","title":"Recommended WordPress plugins","shortTitle":null,"excerpt":"Website performance isn't decided by how many plugins are installed but by the code quality of each one. These are the foundation plugins Perxel uses, with a look at cost and what happens when a licence expires.","categories":["WordPress","Development"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":"2026-08-04","updated":null,"dateModified":"2026-08-04","url":"https://perxel.com/en/insights/wordpress-plugin-list","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"A common misunderstanding among site owners is to judge performance by the number of installed plugins. Some worry that every extra plugin slows the site down, while others install plugins freely to solve each need as it comes up.\n\nIn practice, performance isn't decided by the plugin count. It comes down to the code quality of each plugin and how well the person setting it up understands it. A well-optimised site installs only the tools its real needs call for, instead of chasing a fixed number.\n\nPrices in this article are a rough guide at the time of writing. Licence costs, plans and limits can change, so check the official link for each plugin at the end of the article.\n\nCore plugins\n\nNectarBlocks\n\nA page builder that extends Gutenberg, with visual layouts and deep responsive, hover and animation settings in the admin. On projects Perxel builds, the licence is included in the initial development cost, so the client pays nothing more for the life of the site. When the licence expires, the editor keeps working for editing content and duplicating pages. Only automatic updates and the cloud template library are lost. Official link: nectarblocks.com.\n\nGravity Forms\n\nBuilds contact forms, surveys and sign-up forms with complex logic. Perxel includes the licence in the initial development cost. After it expires, existing forms keep displaying, receiving entries and saving them to the database. Only version updates and extra add-ons are lost. Official link: gravityforms.com.\n\nRank Math SEO or Yoast SEO\n\nHandles meta tags, sitemaps, schema and SEO-friendly content settings. The free version covers most of what a business site needs. The paid version is only worth it for special needs such as multi-location local SEO or advanced product schema. After a licence expires, everything already configured stays in place. Official link: rankmath.com or yoast.com.\n\nSecure Custom Fields\n\nCreates custom input fields in the admin so editors enter content in the structure the design expects. It is the official replacement for the free version of Advanced Custom Fields, and it is free. Official link: wordpress.org/plugins/secure-custom-fields.\n\nPerxel Image Optimizer\n\nAutomatically compresses images and converts them to WebP without visibly lowering quality. It is an open-source product developed by Perxel, free, and on the roadmap for release on the WordPress.org plugin directory.\n\nWP Rocket\n\nCreates a static cache and compresses and optimises CSS and JS files to improve real loading speed. It is a paid plugin, but site owners can use free caching tools from WordPress.org instead, such as LiteSpeed Cache if the host supports it, to cut cost while keeping the site stable. Official link: wp-rocket.me.\n\nMultilingual\n\nWhen a business wants to reach international markets, translating the site is a big technical task. The most established tool today is WPML, which syncs posts, products and images and translates each string in the interface per language. On Perxel projects the licence is included in the initial development cost.\n\nWPML is a suite of add-on plugins that run side by side and use a lot of server resources. On a site built with a heavy prebuilt theme, adding WPML can easily overload the system. On Perxel's custom themes the code is written lean from the start, so the system copes well even with the full WPML suite active.\n\nSecurity and backup\n\nSucuri Security\n\nMonitors file integrity, scans for malware on a schedule and detects unauthorised access. The free version on WordPress.org has all the basic monitoring features. Official link: sucuri.net.\n\nLogin limits and hiding wp-admin\n\nLimits failed login attempts to block password guessing, hides the default login page and sets basic security rules. Plugins in this group, such as Kadence Security or Solid Security, have free versions that cover ordinary needs.\n\nAkeeba Backup\n\nPackages the whole codebase and database and stores them safely, ready to restore if something goes wrong. The free Core version handles manual backup and restore well. The paid version is needed when a business wants scheduled automatic backups and automatic upload to cloud storage. Official link: akeebabackup.com.\n\nAdmin utilities\n\nSmall tools, mostly free, that handle editing tasks and admin customisation:\n\n- White Label CMS. Customises the admin interface, hides unneeded dashboard widgets and sets up a dashboard just for the client.\n- AddToAny Share Buttons. Adds lightweight share buttons for social networks.\n- Regenerate Thumbnails. Rebuilds image sizes when the site's image size settings change.\n- Enable Media Replace. Replaces an old image or PDF with a new file without changing its URL.\n- Better Search Replace. Finds and replaces strings across the database in bulk, for example when changing a hotline number site-wide or moving to a new domain.\n- WP Mail SMTP. Configures an intermediate mail server so emails sent by the site reach the inbox instead of being marked as spam.\n\nIn short\n\nChoosing plugins for a WordPress site doesn't follow a fixed formula. It depends on the real needs of each business. A durable, high-performance site is built on a lean WordPress custom theme (/en/services/wordpress-custom-theme) together with a carefully chosen plugin list, with clear costs and licence risks over the long term.\n\n1. NectarBlocks\n2. Gravity Forms\n3. Rank Math SEO\n4. Yoast SEO\n5. Secure Custom Fields\n6. WP Rocket\n7. WPML\n8. Sucuri Security\n9. Akeeba Backup"}],"products":[{"kind":"product","locale":"vi","slug":"spotlight","title":"Spotlight","shortTitle":null,"excerpt":"Ô tìm kiếm cho website, giống Spotlight trên máy Mac. Người dùng tìm thấy trang cần xem ngay khi đang gõ, đặt câu hỏi và nhận câu trả lời từ chính nội dung website, hoặc mở form liên hệ, tất cả trong một ô.","categories":["Mã nguồn mở"],"tech":[{"id":"react","label":"React"}],"date":"2026-10-13","updated":null,"dateModified":"2026-10-13","url":"https://perxel.com/products/spotlight","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Mã nguồn mở","title":"Xem trên GitHub","href":"https://github.com/perxel/perxel-spotlight"}],"productType":"ai-product","body":"Spotlight giúp website có một ô duy nhất cho mọi việc người dùng cần làm. Khi bấm ⌘K hoặc nút trên thanh menu, các trang phù hợp hiện ra ngay lúc người dùng đang gõ. Nếu chưa thấy điều mình cần, người dùng bấm Enter và AI sẽ trả lời dựa trên nội dung của chính website, kèm danh sách các trang đã dùng. Ask Perxel trên website này đang chạy bằng Spotlight.\n\nVì sao chỉ cần một ô\n\nPhần lớn website đặt bong bóng chat ở một góc và ô tìm kiếm ở một chỗ khác, nên người dùng phải tự đoán nên dùng cái nào. Nhiều khi họ không dùng cái nào và rời trang. Với Spotlight, trang nào cũng có một chỗ bắt đầu rõ ràng.\n\nNgười dùng của bạn nhận được gì\n\n- Tìm thấy trang ngay khi gõ. Kết quả cập nhật theo từng chữ, và từ đã gõ được tô màu để người dùng thấy vì sao kết quả đó phù hợp. Gõ tiếng Việt có dấu hay không dấu đều tìm được.\n- Câu trả lời từ nội dung của bạn, vào bất kỳ giờ nào. AI chỉ trả lời dựa trên những gì website đã viết, và liệt kê các trang liên quan để người dùng đọc thêm.\n- Form liên hệ chỉ cách một từ. Gõ \"liên hệ\" là form hiện ra ngay. Sau một cuộc trò chuyện, AI có thể điền sẵn form từ nội dung người dùng đã hỏi, còn việc gửi hay không vẫn do người dùng quyết định.\n- Dùng trên điện thoại cũng thuận tiện. Nút ở thanh dưới cùng mở ô tìm kiếm, và kết quả được thiết kế để bấm bằng ngón cái.\n\nTrên điện thoại, nút Ask Perxel ở thanh dưới cùng mở ô tìm kiếm.\n\nDoanh nghiệp của bạn nhận được gì\n\n- Website không chậm đi. Spotlight chỉ được tải khi người dùng mở ô, nên tốc độ tải trang vẫn như trước.\n- Có lớp bảo vệ chống lạm dụng. Mỗi câu hỏi đều qua bước kiểm tra bot, mỗi người dùng chỉ được hỏi trong giới hạn nhất định, và chi phí AI mỗi ngày có mức trần.\n- Người dùng đến đúng nội dung nhanh hơn. Người dùng không cần tìm hiểu menu của website: họ gõ điều mình cần và nhận được trang phù hợp hoặc câu trả lời.\n\nĐưa Spotlight lên website của bạn\n\nPerxel thiết lập Spotlight cho bạn: chọn nội dung cần tìm kiếm, kết nối AI với nội dung website, thiết kế theo thương hiệu và kiểm tra trên máy tính lẫn điện thoại. Perxel cũng có thể vận hành Spotlight thay bạn. Tài khoản AI và hosting do Perxel quản lý, và Perxel theo dõi lượt sử dụng lẫn chi phí, nên bạn không phải quản lý thêm tài khoản nào. Spotlight là mã nguồn mở, nên phần code thuộc về website của bạn. Spotlight cũng đang chạy trên phucbm.com. Developer có thể xem mã nguồn trên GitHub.\n\nTrao đổi với Perxel về Spotlight cho website của bạn (/contact)\n\n1. perxel-spotlight trên GitHub"},{"kind":"product","locale":"vi","slug":"perxel-social-kit","title":"Perxel Social Kit","shortTitle":null,"excerpt":"Công cụ mã nguồn mở tạo ảnh và video ngắn cho mạng xã hội từ template React: viết một bài đăng, kit render đủ các kích thước vuông, 16:9 và 9:16. Kit cũng tạo ảnh và video minh họa cho bài viết trên website từ một file công thức.","categories":["Mã nguồn mở"],"tech":[{"id":"react","label":"React"}],"date":"2026-10-12","updated":null,"dateModified":"2026-10-12","url":"https://perxel.com/products/perxel-social-kit","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Mã nguồn mở","title":"Xem trên GitHub","href":"https://github.com/perxel/perxel-social-kit"}],"productType":"tool","body":"Perxel Social Kit là bộ công cụ mã nguồn mở giúp AI agent tạo ảnh và video ngắn cho mạng xã hội. Bạn mô tả bài đăng cho agent đang dùng (Claude Code, Cursor hoặc agent khác), agent dùng kit để render bài đó ra ảnh vuông 1:1, ảnh ngang 16:9 và ảnh dọc 9:16 (hoặc video), rồi tự xem lại tất cả kích thước trước khi gửi kết quả. Template là component React nằm ngay trong repo của dự án, nên hình ảnh mang đúng thương hiệu của bạn.\n\nBài toán\n\nMỗi lần đăng bài, cùng một nội dung cần nhiều kích thước: ảnh vuông cho LinkedIn, ảnh ngang cho X và website, ảnh dọc cho Stories, Reels và TikTok. Nếu làm bằng công cụ thiết kế thì mỗi kích thước là một file riêng, và mỗi lần sửa chữ lại phải sửa ở tất cả các file. Ảnh dọc còn có thêm một rủi ro: phần trên và phần dưới màn hình bị các nút của ứng dụng che mất.\n\nVới Social Kit, nội dung nằm ở một chỗ và bố cục cho từng kích thước nằm trong template. Khi cần sửa, bạn chỉ cần nói với agent.\n\nCài đặt và cách dùng\n\nChạy npx @perxel/social-kit init trong repo của dự án. Lệnh này cài kit, tạo thư mục social/ với bài đăng đầu tiên và cài skill hướng dẫn agent cách dùng kit. Sau đó, bạn chỉ cần nhờ agent, ví dụ: \"Tạo bài đăng thông báo ra mắt sản phẩm mới, đủ các kích thước\".\n\nSkill hướng dẫn agent làm theo đúng quy trình: kiểm tra môi trường, dùng màu, font và template có sẵn của dự án, render mọi kích thước, rồi tự xem contact sheet để sửa chữ tràn khung hoặc nội dung nằm trong vùng bị che trước khi gửi bạn. Agent không tự thêm câu chữ bạn chưa duyệt mà chỉ đề xuất. Nếu muốn tự chạy các lệnh của kit, xem hướng dẫn trên GitHub.\n\nKit làm được gì\n\n- Đủ mọi kích thước trong một lần render. Các file được đặt tên theo bài đăng (ví dụ launch-square.png, launch-portrait.mp4), kèm một contact sheet để xem tất cả cạnh nhau.\n- Bố cục riêng cho từng kích thước. Ảnh dọc có thể sắp xếp khác ảnh ngang thay vì chỉ thu nhỏ, và chừa trống vùng bị nút ứng dụng che.\n- Video ngắn khớp nhịp nhạc. Kit đọc tempo và nhịp của bài nhạc, nên agent có thể chuyển cảnh đúng phách. Phần video được dựng bằng Remotion.\n- Một chiến dịch trong một thư mục. Một template có thể vẽ cả ảnh tĩnh lẫn video, nên một bài đăng cho ra đủ ảnh và video của cùng một chiến dịch.\n- Ảnh và video cho bài viết trên website. Agent có thể chụp trang web đang chạy, quay video ngắn các thao tác (cuộn trang, gõ phím, bấm ⌘K) và dựng ảnh minh họa từ template. Các bước được lưu thành một file công thức, nên khi giao diện thay đổi, agent tạo lại toàn bộ hình ảnh theo đúng công thức đó.\n\nPerxel dùng kit như thế nào\n\nCác ảnh và video Perxel đăng trên mạng xã hội, cùng phần lớn hình ảnh trong bài viết trên website này, đều được tạo bằng Social Kit qua AI agent. Template, logo và nhạc nằm trong repo của website, còn kit chỉ lo phần render, nên mọi thay đổi về thương hiệu đều được sửa trong repo website.\n\nGiấy phép\n\nKit phát hành theo giấy phép MIT trên GitHub và npm. Phần video và template chạy trên trình duyệt dùng Remotion, thư viện này miễn phí cho cá nhân và công ty tối đa 3 người, công ty lớn hơn cần mua giấy phép của Remotion. Ảnh tĩnh thông thường không cần Remotion.\n\n1. perxel-social-kit trên GitHub\n2. @perxel/social-kit trên npm\n3. Giấy phép Remotion"},{"kind":"product","locale":"vi","slug":"perxel-accordion-for-tinymce","title":"Perxel Accordion for TinyMCE","shortTitle":null,"excerpt":"Plugin mã nguồn mở thêm nút tạo accordion vào Classic Editor của WordPress. Xem trước ngay trong tab Visual, hiển thị trên frontend theo chuẩn accessibility, không cần cấu hình và không lưu gì vào database.","categories":["WordPress Plugin","Mã nguồn mở"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":"2026-09-27","updated":"2026-09-29","dateModified":"2026-09-29","url":"https://perxel.com/products/perxel-accordion-for-tinymce","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"WordPress.org","title":"Cài đặt từ thư mục plugin","href":"https://wordpress.org/plugins/perxel-accordion-for-tinymce/"},{"caption":"Mã nguồn mở","title":"Xem trên GitHub","href":"https://github.com/perxel/perxel-accordion-for-tinymce"}],"productType":"wordpress-plugin","body":"Perxel Accordion for TinyMCE là plugin mã nguồn mở giúp tạo accordion trong Classic Editor của WordPress chỉ với vài cú click. Nút Accordion có mặt ở mọi nơi dùng Classic Editor: trang soạn bài viết, widget, và cả trường WYSIWYG của ACF.\n\nBối cảnh\n\nMuốn thêm một khối nội dung thu gọn như \"Xem thêm\" hay phần câu hỏi thường gặp trong Classic Editor, người viết thường phải tự gõ HTML hoặc cài cả một page builder. TinyMCE có sẵn plugin accordion, nhưng plugin này chỉ chạy từ TinyMCE 6, còn Classic Editor của WordPress vẫn đang dùng TinyMCE 4.\n\nPerxel Accordion for TinyMCE lấp khoảng trống đó bằng một nút bấm trên thanh công cụ. Không có trang cài đặt, không lưu gì vào database.\n\nTạo accordion ngay trong trình soạn thảo\n\nBấm nút Accordion trên thanh công cụ, điền tiêu đề và nội dung rồi chèn. Phần nội dung là một Classic Editor thu nhỏ nên bạn vẫn in đậm, chèn link hay tạo danh sách như bình thường.\n\nChèn một accordion từ thanh công cụ.\n\nBạn có thể chọn thẻ cho tiêu đề (div, p hoặc h1 đến h6) nếu muốn tiêu đề là một heading trong bài, và tick Open by default nếu muốn accordion mở sẵn khi tải trang.\n\nPlugin chèn một shortcode [pxta_accordion] vào bài. Ở tab Visual, bạn thấy accordion y như trên frontend và bấm biểu tượng bút chì để sửa. Ở tab Text, bạn thấy shortcode gốc.\n\nHiển thị trên frontend\n\nAccordion được dựng theo chuẩn accessibility, dùng tốt với bàn phím và trình đọc màn hình. CSS và JavaScript của plugin rất nhẹ và chỉ tải trên những trang có accordion.\n\nAccordion với giao diện mặc định.\n\nNếu theme đã có jQuery, nội dung sẽ trượt mượt khi đóng mở. Nếu không có jQuery, hoặc người xem đã tắt hiệu ứng chuyển động trên thiết bị, accordion đóng mở tức thì.\n\nDùng shortcode trực tiếp\n\nShortcode dùng được ở bất cứ đâu WordPress xử lý shortcode: template, Shortcode block trong Block Editor, hay trang dựng bằng shortcode.\n\n[pxta_accordion title=\"Chi phí thế nào?\" title_tag=\"h3\" open=\"1\"]Hoàn toàn miễn phí.[/pxta_accordion]\n\nTùy chỉnh giao diện\n\nGiao diện mặc định gọn gàng: nền xám nhạt, bo góc, mũi tên bên phải. Muốn đổi, bạn có ba cách:\n\n- Viết CSS trong theme cho .pxta-accordion và .pxta-accordioncontent. Accordion đang mở có thêm class pxta-accordion--open.\n- Tắt hẳn CSS mặc định bằng filter pxta_accordion_load_css.\n- Thay toàn bộ HTML bằng filter pxta_accordion_html.\n\nCài đặt và yêu cầu hệ thống\n\nPlugin có trên WordPress.org. Vào Plugins, chọn Add New, tìm \"Perxel Accordion for TinyMCE\" và kích hoạt. Không cần cấu hình gì thêm, mở một bài viết là thấy nút Accordion.\n\n- WordPress 6.5 trở lên, PHP 7.4 trở lên.\n- Đang dùng Classic Editor, ví dụ qua plugin Classic Editor.\n- Với ACF, trường WYSIWYG cần đặt Toolbar là Full, vì toolbar Basic không cho thêm nút.\n\nKhi gỡ plugin, các shortcode trong bài vẫn còn nguyên, chỉ không hiển thị thành accordion nữa.\n\nMã nguồn công khai trên GitHub, miễn phí và không quảng cáo. Plugin được xây trên WP Plugin Toolkit (/products/wp-plugin-toolkit) và thường đi kèm các dự án custom plugin (/services/wordpress-plugins) tại Perxel.\n\nTinyMCE là nhãn hiệu của Tiny Technologies, Inc. Plugin này độc lập, không liên kết với hay được bảo trợ bởi Tiny Technologies, Inc.\n\n1. Perxel Accordion for TinyMCE trên WordPress.org\n2. Perxel Accordion for TinyMCE trên GitHub\n3. TinyMCE Accordion plugin\n4. Classic Editor trên WordPress.org\n5. Advanced Custom Fields"},{"kind":"product","locale":"vi","slug":"foldables","title":"Foldables","shortTitle":null,"excerpt":"Bộ khung marketing website xây dựng để kiểm chứng stack Next.js, Prismic và Cloudflare Workers trong một dự án thực tế, từ content modeling qua CLI đến preview và deploy.","categories":["Next.js","Mã nguồn mở"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"prismic","label":"Prismic"},{"id":"cloudflare","label":"Cloudflare"},{"id":"tailwind","label":"Tailwind CSS"}],"date":"2026-09-15","updated":null,"dateModified":"2026-09-15","url":"https://perxel.com/products/foldables","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Dịch vụ liên quan","title":"Website Next.js & Headless CMS","href":"/services/nextjs"}],"productType":"proof-of-concept","body":"Foldables là dự án thực nghiệm do Perxel nghiên cứu và phát triển, nhằm kiểm chứng trọn vẹn stack Next.js, Prismic và Cloudflare Workers từ khâu content modeling qua CLI đến triển khai trên hạ tầng Edge.\n\nChỉ số kỹ thuật và tổng quan\n\n- Môi trường triển khai: Cloudflare Workers (Edge Network), qua OpenNext Cloudflare adapter, không dùng Vercel hay Cloudflare Pages\n- Quy mô cấu trúc: 1 page type (Page) và 1 singleton (Home), demo với 1 slice (Hero)\n- Cơ chế cập nhật nội dung: Revalidate tự động qua Webhook khi publish trên Prismic\n- Preview: Full-website preview và Slice Simulator tích hợp trực tiếp trong Prismic Page Builder\n\nBối cảnh và mục tiêu\n\nĐây là loại dự án phổ biến với marketing team: cần một website nhanh, chuẩn SEO, có giao diện quản trị chuyên nghiệp cho team không chuyên kỹ thuật, nhưng vẫn triển khai được trên hạ tầng Edge Network thay vì phụ thuộc vào Vercel mặc định.\n\nBộ khung Foldables hướng tới ba tiêu chí đồng thời:\n\nToàn bộ page type và slice được quản lý qua Prismic CLI, không chỉnh sửa tay các tệp JSON định nghĩa model, giữ model luôn đồng bộ giữa local và Prismic dashboard.\n\nTeam biên tập xuất bản nội dung qua Prismic Page Builder, xem trước layout thực tế trong ô preview riêng trước khi publish.\n\nToàn bộ frontend và route handler của Next.js chạy trên Cloudflare Workers qua OpenNext, tận dụng mạng lưới Edge thay vì một máy chủ tập trung.\n\nQuản trị nội dung với Prismic\n\nFoldables tích hợp Prismic theo mô hình SaaS, quản lý content type và slice qua CLI thay vì chỉnh sửa thủ công.\n\nBiên tập nội dung qua Page Builder, xem trước từng slice trước khi publish.\n\n- Content modeling qua CLI. Page type và slice được tạo và đồng bộ bằng lệnh npx prismic type create và npx prismic slice create, giữ model nhất quán giữa mã nguồn và dashboard.\n- Xuất bản qua Page Builder. Nội dung thực tế được tạo và publish trực tiếp trong Prismic dashboard, tách biệt hoàn toàn với việc định nghĩa cấu trúc.\n- Revalidate tức thì. Một webhook lắng nghe sự kiện publish từ Prismic và kích hoạt revalidate, giúp trang tĩnh cập nhật ngay mà không cần rebuild toàn bộ site.\n\nHạ tầng triển khai trên Cloudflare Workers\n\nVercel là lựa chọn mặc định và tương thích tự nhiên nhất với Next.js. Với Foldables, Perxel áp dụng lại giải pháp tích hợp qua OpenNext để vận hành ứng dụng trên Cloudflare Workers, đã được kiểm chứng trước đó qua dự án Atlas Robotics (/products/atlas-robotics).\n\n- Tối ưu chi phí vận hành. Cloudflare có gói miễn phí rộng rãi, hầu như không phát sinh chi phí hạ tầng ở quy mô truy cập của một marketing website.\n- Mạng lưới Edge toàn cầu. Dữ liệu được phản hồi từ máy chủ gần người dùng nhất, giữ tốc độ phản hồi nhanh ở mọi vị trí địa lý.\n- Custom domain và cache riêng. Cấu hình domain và R2 cache được quản lý trực tiếp qua Wrangler, tách biệt với môi trường dev.\n\nGiá trị ứng dụng cho dự án khách hàng\n\nFoldables là bộ khung kỹ thuật đã được kiểm chứng cho stack Next.js kết hợp Prismic. Khi triển khai dự án cho khách hàng chọn Prismic, Perxel không mất thời gian thiết lập lại content modeling hay hạ tầng deploy từ đầu, toàn bộ nguồn lực tập trung vào thiết kế giao diện độc bản và tối ưu trải nghiệm cho từng doanh nghiệp.\n\nXem thêm dịch vụ Website Next.js & Headless CMS (/services/nextjs). Bản demo đang chạy tại foldables.perxel.com."},{"kind":"product","locale":"vi","slug":"perxel-ai-translate","title":"Perxel AI Translate","shortTitle":null,"excerpt":"Plugin WPML AI Translation mã nguồn mở, dịch hàng loạt bài viết WordPress sang các ngôn ngữ của WPML bằng model AI bạn chọn qua OpenRouter. Trả tiền trực tiếp cho OpenRouter, không dùng credit của WPML, xem trước chi phí trước khi chạy.","categories":["WordPress Plugin","Mã nguồn mở"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"wpml","label":"WPML"},{"id":"openrouter","label":"OpenRouter"},{"id":"gemini","label":"Gemini"}],"date":"2026-09-01","updated":"2026-09-27","dateModified":"2026-09-27","url":"https://perxel.com/products/perxel-ai-translate","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"WordPress.org","title":"Cài đặt từ thư mục plugin","href":"https://wordpress.org/plugins/perxel-ai-translate/"},{"caption":"Mã nguồn mở","title":"Xem trên GitHub","href":"https://github.com/perxel/wp-ai-translate"}],"productType":"wordpress-plugin","body":"Perxel AI Translate là plugin WPML AI Translation mã nguồn mở, dịch bài viết, trang và custom post type sang các ngôn ngữ đã cài trong WPML. Plugin gửi nội dung tới model AI bạn chọn qua OpenRouter, rồi ghi kết quả thẳng vào WordPress dưới dạng bản dịch WPML. Plugin ra đời từ dự án Khatra Tile (/works/khatra), khi cần dịch khoảng 1.000 bài viết và sản phẩm sang tiếng Anh.\n\nBối cảnh\n\nWPML có sẵn tính năng dịch tự động, nhưng tính phí theo credit. Website càng nhiều nội dung thì chi phí càng cao, và bạn không chọn được model nào sẽ dịch. Perxel AI Translate dùng API key OpenRouter của chính bạn: bạn chọn model, trả tiền trực tiếp cho OpenRouter, không phải mua credit của bên nào khác.\n\nDịch hàng loạt bài viết WPML bằng AI\n\nTrong danh sách bài viết, chọn các bài cần dịch rồi chọn Perxel AI Translate… trong Bulk actions. Nếu đang sửa một bài, bạn bấm Translate this page trên thanh công cụ.\n\nMàn hình Translation: chọn ngôn ngữ đích và dữ liệu cần dịch, xem ước tính số từ và chi phí trước khi chạy.\n\nBấm Translate and apply để bắt đầu. Bạn có thể đóng tab bất cứ lúc nào, sau đó mở lại lượt dịch và bấm Resume để chạy tiếp. Nếu một bài bị lỗi, bạn thử lại riêng bài đó, bản dịch đã có sẽ được dùng lại nên không mất thêm tiền gọi model. Mọi lượt dịch được lưu trong Tools → AI Translate → History.\n\nMàn hình History: mỗi lượt dịch kèm ngôn ngữ, model, số bài, cảnh báo hoặc lỗi, số từ và chi phí.\n\nNhững gì được dịch\n\n- Nội dung chính. Title, slug, excerpt và content. HTML và shortcode của page builder như WPBakery được giữ nguyên, chỉ phần chữ được dịch.\n- Custom fields. Các trường text, textarea và WYSIWYG của ACF và SCF, kể cả trường nằm trong Group, Repeater và Flexible Content. Các loại trường khác được chép nguyên sang bản dịch.\n- SEO. Title, description, focus keyword và social meta của Rank Math.\n- Taxonomy và ảnh đại diện. Term được gắn sang bản dịch WPML tương ứng, ảnh đại diện dùng bản dịch của WPML Media Translation nếu có.\n\nChọn model và kiểm soát chi phí qua OpenRouter\n\nBạn dùng được mọi model có trên OpenRouter (Gemini, Claude, GPT…). Mặc định là một model Gemini Flash giá rẻ. Settings kiểm tra API key, cho biết key còn bao nhiêu credit và cảnh báo khi chi phí ước tính vượt quá số credit đó. Nếu ngôn ngữ mặc định của website là tiếng Việt, chi phí được hiển thị bằng VND.\n\nMàn hình Settings: API key và model, tùy chọn dịch theo lô, Extra instructions và các plugin đã phát hiện.\n\nMục Extra instructions dùng để giữ đúng thuật ngữ ngành, tên riêng và giọng thương hiệu trong mọi lần dịch. Tùy chọn Faster batched requests (bật sẵn) gửi nhiều bài ngắn trong một lần gọi model để dịch nhanh hơn.\n\nCài đặt và yêu cầu hệ thống\n\nPlugin có trên WordPress.org. Sau khi kích hoạt, vào Tools → AI Translate → Settings và nhập API key OpenRouter.\n\n- WordPress 6.2 trở lên, PHP 7.4 trở lên.\n- WPML (Multilingual CMS trở lên) có ít nhất hai ngôn ngữ. Nếu không có WPML, plugin sẽ không hoạt động.\n- Tài khoản và API key OpenRouter.\n\nĐã thử với WPML 4.9.7, Secure Custom Fields 6.9.5, Rank Math SEO 1.0.277.2 (PRO 3.0.82) và WPBakery 9.0.1.\n\nMã nguồn công khai trên GitHub. Plugin được xây trên WP Plugin Toolkit (/products/wp-plugin-toolkit) và thường đi kèm các dự án custom plugin (/services/wordpress-plugins) tại Perxel.\n\n1. Perxel AI Translate trên WordPress.org\n2. Perxel AI Translate trên GitHub\n3. OpenRouter\n4. WPML\n5. Rank Math\n6. Advanced Custom Fields"},{"kind":"product","locale":"vi","slug":"perxel-image-optimizer","title":"Perxel Image Optimizer","shortTitle":null,"excerpt":"Plugin mã nguồn mở chuyển ảnh WordPress sang WebP ngay trên máy chủ, không cần API key hay dịch vụ bên thứ ba. Hỗ trợ xử lý hàng loạt trên shared hosting và dễ dàng gỡ bỏ khi không còn sử dụng.","categories":["WordPress Plugin","Mã nguồn mở"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":"2026-08-15","updated":"2026-09-22","dateModified":"2026-09-22","url":"https://perxel.com/products/perxel-image-optimizer","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"WordPress.org","title":"Cài đặt từ thư mục plugin","href":"https://wordpress.org/plugins/perxel-image-optimizer/"},{"caption":"Mã nguồn mở","title":"Xem trên GitHub","href":"https://github.com/perxel/wp-image-optimizer"}],"productType":"wordpress-plugin","body":"Perxel Image Optimizer là plugin mã nguồn mở giúp chuyển ảnh trong thư viện WordPress sang WebP. Toàn bộ quá trình chuyển đổi chạy ngay trên máy chủ của website, không cần CDN, API key hay tài khoản. Ảnh gốc vẫn nằm trên hosting của bạn.\n\nBối cảnh\n\nChuyển ảnh sang WebP gần như là bước bắt buộc khi tối ưu Core Web Vitals. Nhưng nhiều plugin phổ biến như ShortPixel và Imagify gửi ảnh lên máy chủ của họ để nén, yêu cầu tạo tài khoản và giới hạn dung lượng hoặc số ảnh miễn phí mỗi tháng. Với website có thư viện media lớn, đó là một khoản phí định kỳ và thêm một hệ thống bên ngoài phải phụ thuộc vào.\n\nPerxel Image Optimizer làm đúng việc đó theo cách đơn giản hơn: nhẹ, miễn phí, chuyển đổi ngay trên server và chạy được trên shared hosting.\n\nChuyển ảnh WordPress sang WebP ngay trên server\n\nPlugin dùng WP_Image_Editor (GD hoặc Imagick) có sẵn trên server để tạo file .webp cạnh file gốc, ví dụ image.jpg thành image.jpg.webp. Ảnh gốc không bị sửa hay thay thế.\n\nĐể hiển thị ảnh WebP cho người truy cập, plugin tự chọn cách phù hợp với server:\n\n- Apache và LiteSpeed. Một khối .htaccess do plugin quản lý sẽ trả file .webp khi trình duyệt gửi header Accept: image/webp. HTML của trang không đổi.\n- Nginx. Khi không ghi được .htaccess, plugin đổi thẻ thành khi render trang.\n\nTùy chọn này mặc định đang tắt. Bạn có thể bật hoặc tắt trong Settings. Tắt đi thì mọi người lại nhận ảnh gốc, không có file nào bị xóa.\n\nChuyển hàng loạt ảnh trên shared hosting\n\nTrước khi chạy, màn hình Optimization cho biết trước những gì sắp diễn ra: số ảnh trong thư viện, số ảnh bị bỏ qua vì quá lớn, thời gian ước tính và các thiết lập đang dùng. Bạn chọn phạm vi (cả thư viện hoặc từng tháng) và một trong hai chế độ chạy.\n\nMàn hình Optimization: thư viện 15.040 ảnh, ước tính tối đa khoảng 21 phút.\n\n- Background. Chạy nền bằng Action Scheduler, đi từ ảnh mới nhất đến cũ nhất theo từng tháng và bỏ qua ảnh đã có .webp. Bạn có thể đóng tab, tiến trình vẫn tiếp tục. Có nút tạm dừng, tiếp tục và hủy.\n- Fast. Dành cho shared hosting không có cron ổn định. Tab quản trị đang mở sẽ điều khiển việc chuyển đổi nên server chạy liên tục và nhanh hơn nhiều. Nếu host bắt đầu quá tải, plugin tự tạm dừng rồi chạy lại sau một lúc. Khi đang chạy, bạn có thể chỉnh tốc độ giữa Gentle, Balanced và Turbo.\n\nDừng hoặc hủy giữa chừng không làm mất các file đã chuyển. Lần sau plugin chạy tiếp từ chỗ đã dừng. Bạn cũng có thể bật email báo cáo khi chạy xong, gồm số ảnh đã chuyển, băng thông tiết kiệm, dung lượng đĩa tăng thêm và các lỗi nếu có.\n\nChất lượng nén và kích thước ảnh\n\nTrang Settings chia thành các nhóm Conversion, Serving và Notifications.\n\nMàn hình Settings: chất lượng nén, kích thước cần chuyển, ảnh tải lên mới và email thông báo.\n\n- Chất lượng. JPEG mặc định 80, PNG mặc định 90. PNG được chuyển không mất dữ liệu nên thiết lập này chỉ đổi dung lượng file.\n- Kích thước ảnh. Chọn riêng từng size (full, thumbnail, medium, large và các size do theme thêm) để không tạo những file .webp không dùng đến.\n- PNG. Mặc định chỉ chuyển JPEG. Bật thêm nếu bạn muốn chuyển cả PNG.\n- Giới hạn megapixel. Ảnh lớn hơn ngưỡng này sẽ bị bỏ qua để tránh hết bộ nhớ. Để 0 thì plugin dùng ngưỡng tính theo cấu hình server (ví dụ 16 MP).\n- Ảnh mới tải lên. Bật tự động tối ưu để ảnh được chuyển sang WebP ngay sau khi upload.\n\nChuyển hoặc xóa WebP của từng ảnh\n\nTrong Media Library, mỗi ảnh có các nút Convert, Reconvert và Remove, ở cả dạng danh sách lẫn khung chi tiết. Muốn chuyển lại một ảnh sau khi đổi chất lượng, hoặc xóa WebP của riêng ảnh đó, bạn không phải chạy lại cả thư viện.\n\nGỡ plugin và xóa file WebP\n\nSettings có khu vực xóa toàn bộ file .webp đã tạo và khối .htaccess đã thêm, đưa website về trạng thái ban đầu chỉ với một thao tác. Khi xóa plugin, các option, post meta và khối .htaccess sẽ được dọn đi. File .webp thì được giữ lại, nên hãy chạy thao tác xóa trước nếu muốn xóa cả chúng.\n\nCài đặt và yêu cầu hệ thống\n\nPlugin có trên WordPress.org. Vào Plugins, chọn Add New, tìm \"Perxel Image Optimizer\", kích hoạt rồi mở Media → Optimization.\n\n- PHP 7.4 trở lên, WordPress 6.5 trở lên.\n- GD hoặc Imagick có hỗ trợ WebP. Nếu thiếu, trang quản trị sẽ dừng lại và báo rõ.\n- Apache hoặc LiteSpeed với .htaccess ghi được để không phải đổi HTML. Các môi trường khác dùng .\n\nMã nguồn công khai trên GitHub, miễn phí và không quảng cáo. Plugin được xây trên WP Plugin Toolkit (/products/wp-plugin-toolkit) và thường đi kèm các dự án WordPress custom theme (/services/wordpress-custom-theme) tại Perxel.\n\n1. Perxel Image Optimizer trên WordPress.org\n2. ShortPixel Image Optimizer trên WordPress.org\n3. Imagify trên WordPress.org\n4. Perxel Image Optimizer trên GitHub\n5. Action Scheduler"},{"kind":"product","locale":"vi","slug":"atlas-robotics","title":"Atlas Robotics","shortTitle":null,"excerpt":"Bộ khung marketing website B2B và công nghệ, xây dựng để kiểm chứng stack Next.js, TinaCMS và Cloudflare Workers trong một dự án thực tế với nội dung đa ngôn ngữ.","categories":["Next.js","Mã nguồn mở"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"},{"id":"tailwind","label":"Tailwind CSS"}],"date":"2026-08-13","updated":null,"dateModified":"2026-08-13","url":"https://perxel.com/products/atlas-robotics","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Insights","title":"Certified Developer by TinaCMS","href":"/insights/certified-tinacms-developer"}],"productType":"proof-of-concept","body":"Atlas Robotics là dự án thực nghiệm do Perxel nghiên cứu và phát triển. Mục tiêu là xây dựng một bộ khung mã nguồn (boilerplate) đạt chuẩn cho nhóm website B2B và công nghệ, kiểm chứng stack Next.js, TinaCMS và Cloudflare Workers trong một sản phẩm hoàn chỉnh, sẵn sàng cho môi trường production.\n\nChỉ số kỹ thuật và hiệu năng\n\n[//]: # (- Điểm PageSpeed Insights &#40;mobile / desktop&#41;: 98/100 mobile, 100/100 desktop)\n- Thời gian phản hồi trang (TTFB tại Edge): < 50ms\n- Quy mô cấu trúc: 3 collections chính (Products, Blog, Pages)\n- Cấu hình đa ngôn ngữ: demo 3 ngôn ngữ (EN / VI / ZH), kiến trúc hỗ trợ mở rộng\n- Môi trường triển khai: Cloudflare Workers (Edge Network)\n\nBối cảnh và mục tiêu\n\nĐây là loại dự án phổ biến với marketing team: cần một website nhanh, chuẩn SEO, hỗ trợ nhiều ngôn ngữ, nhưng vẫn phải dễ tự cập nhật nội dung sau khi launch mà không phát sinh thêm chi phí CMS hay hosting theo quy mô nội dung.\n\nBộ khung Atlas Robotics hướng tới ba tiêu chí đồng thời:\n\nToàn bộ frontend xây dựng trên Next.js, tối ưu performance và Core Web Vitals ngay từ kiến trúc. Dữ liệu được phản hồi từ máy chủ gần người dùng nhất trên mạng lưới Edge.\n\nTinaCMS cho phép team biên tập chỉnh sửa văn bản, hình ảnh và nội dung đa ngôn ngữ, xem trước thay đổi trực tiếp trên màn hình trước khi xuất bản.\n\nĐa ngôn ngữ được xử lý ngay từ tầng mã nguồn, dễ dàng bổ sung ngôn ngữ mới mà không ảnh hưởng đến cấu trúc hiện tại.\n\nQuản trị nội dung với TinaCMS\n\nAtlas Robotics tích hợp TinaCMS theo cơ chế Git-backed, lưu trữ tệp JSON và MDX trực tiếp trong mã nguồn dự án.\n\nChỉnh sửa văn bản và hình ảnh ngay trên giao diện thật của trang chủ.\n\n- Trực quan hóa biên tập. Người nhập liệu chỉnh sửa văn bản, hình ảnh và xem trước thay đổi ngay trên màn hình (live preview) trước khi xuất bản.\n- Quản lý theo schema định sẵn. Nội dung được cấu trúc thành từng block (Hero, Features, Product Catalog, Contact Form) dựa trên schema thiết lập trước. Khác với các công cụ dựng trang tự do dễ làm lệch chuẩn thiết kế, các block trong TinaCMS dùng layout cố định, bảo toàn font chữ, khoảng cách và tính responsive đã thống nhất.\n- Lưu trữ trong mã nguồn. Toàn bộ dữ liệu bài viết và sản phẩm nằm trong repository dự án, không cần duy trì cơ sở dữ liệu bên ngoài.\n\nMỗi trang là một tệp Markdown riêng trong collection Pages, quản lý trực tiếp trong repository.\n\nCấu trúc đa ngôn ngữ tích hợp\n\nAtlas Robotics xử lý đa ngôn ngữ ngay từ tầng kiến trúc mã nguồn, thay vì phụ thuộc vào plugin bên thứ ba như cách làm phổ biến trên các CMS truyền thống (WordPress thường dùng WPML).\n\nNội dung từng ngôn ngữ tách riêng theo thư mục: en, vi, zh.\n\n- Tối ưu chi phí và hiệu năng. Kiến trúc i18n tích hợp sẵn giúp hệ thống vận hành nhẹ, không tốn chi phí bản quyền plugin.\n- Demo 3 ngôn ngữ. Bản thực nghiệm thiết lập sẵn tiếng Anh, Việt và Trung để kiểm thử luồng dữ liệu và cấu trúc đường dẫn chuẩn SEO (/[lang]/...).\n- Mở rộng linh hoạt. Có thể bổ sung ngôn ngữ mới theo nhu cầu mà không ảnh hưởng đến cấu trúc mã nguồn hiện tại.\n\nHạ tầng triển khai trên Cloudflare Workers\n\nVercel là lựa chọn mặc định và tương thích tự nhiên nhất với Next.js. Với Atlas Robotics, Perxel nghiên cứu giải pháp tích hợp qua OpenNext để vận hành ứng dụng trên Cloudflare Workers.\n\n- Tối ưu chi phí vận hành. Cloudflare có gói miễn phí rộng rãi. Với lượng truy cập dưới 100.000 lượt mỗi ngày, website hầu như không phát sinh chi phí hạ tầng.\n- Mạng lưới Edge toàn cầu. Dữ liệu được phản hồi từ máy chủ gần người dùng nhất, giữ tốc độ phản hồi nhanh ở mọi vị trí địa lý.\n\nGiá trị ứng dụng cho dự án khách hàng\n\nAtlas Robotics là bộ khung kỹ thuật đã được kiểm chứng. Khi triển khai dự án cho khách hàng, Perxel không mất thời gian thiết lập lại hạ tầng từ đầu, toàn bộ nguồn lực tập trung vào việc nghiên cứu yêu cầu nghiệp vụ, thiết kế giao diện độc bản và tối ưu trải nghiệm cho từng doanh nghiệp.\n\nQuá trình nghiên cứu và chuẩn hóa stack Next.js, TinaCMS qua dự án này cũng là nền tảng để Perxel nhận chứng nhận Certified Developer từ TinaCMS (/insights/certified-tinacms-developer).\n\nXem thêm dịch vụ Website Next.js & Headless CMS (/services/nextjs). Bản demo đang chạy tại atlas-robotics.perxel.com."},{"kind":"product","locale":"vi","slug":"wp-plugin-toolkit","title":"WP Plugin Toolkit","shortTitle":null,"excerpt":"Bộ khung mã nguồn mở để dựng plugin WordPress: template repo có sẵn autoloading, CI kiểm chuẩn và quy trình phát hành, đi kèm bộ giao diện admin dùng chung. Perxel dùng chính bộ này cho mọi plugin của mình.","categories":["WordPress Plugin","Mã nguồn mở"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":"2026-08-01","updated":"2026-10-10","dateModified":"2026-10-10","url":"https://perxel.com/products/wp-plugin-toolkit","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Mã nguồn mở","title":"Xem trên GitHub","href":"https://github.com/perxel/wp-plugin-starter"}],"productType":"tool","body":"WP Plugin Toolkit là bộ khung mã nguồn mở Perxel dùng để dựng plugin WordPress, gồm hai phần: một template repository cho phần backend và một bộ giao diện admin dùng chung cho phần frontend. Đây là nền tảng chuẩn cho mọi plugin do Perxel phát triển, gồm cả Perxel Image Optimizer (/products/perxel-image-optimizer), Perxel AI Translate (/products/perxel-ai-translate) và Perxel Accordion for TinyMCE (/products/perxel-accordion-for-tinymce). Các plugin này đều đã được duyệt lên thư mục plugin WordPress.org.\n\nBài toán\n\nKhi bắt đầu một plugin mới, phần lớn thời gian đầu không dành cho tính năng mà cho việc dựng lại bộ khung: cấu trúc thư mục, autoloading, các hook kích hoạt và gỡ bỏ, cấu hình build và CI. Sau đó là viết lại CSS và JS cho các trang cài đặt, và mỗi plugin lại lệch nhau một chút về bố cục và thao tác.\n\nWP Plugin Toolkit gộp cả hai phần này thành một điểm khởi đầu chung, để công sức tập trung vào phần logic nghiệp vụ.\n\nTemplate repository: wp-plugin-starter\n\nwp-plugin-starter là một GitHub template repository. Tạo repo mới từ nó là có ngay một plugin chạy được: codebase đã đặt namespace và autoload theo PSR-4, một màn hình Settings mẫu render trong bố cục dùng chung, PHPCS và WordPress Plugin Check chạy trong CI, và một workflow đóng gói file zip cài đặt rồi phát hành lên WordPress.org.\n\nTạo một plugin mới từ toolkit\n\nCác bước đều có trong README của repo, không cần công cụ riêng:\n\n1. Tạo repo mới từ template. Trên GitHub, chọn Use this template rồi clone về máy.\n2. Thay sáu token đặt tên (namespace, tên hiển thị, slug, tên repo, tiền tố hằng số và tiền tố hook) bằng một lệnh sed, sau đó đổi tên file chính và file .pot. Không có bước build.\n3. Thêm bộ giao diện admin nếu plugin có trang cài đặt. Chạy bin/update-ui.sh với version mới nhất của wp-plugin-ui. Plugin chỉ chạy trong editor hoặc qua shortcode thì bỏ qua bước này.\n4. Kiểm tra và đóng gói. composer run lint chạy PHPCS, composer run build tạo file zip cài đặt trong dist/.\n5. Phát hành. Sau khi WordPress.org duyệt lần đầu, mỗi bản Release trên GitHub sẽ tự đẩy lên WordPress.org.\n\nBộ giao diện admin: wp-plugin-ui\n\nwp-plugin-ui là một lớp giao diện admin nhẹ, render phía server bằng PHP với vài dòng JS thuần, không framework và không bước build. Nó cung cấp một bố cục chính gồm sidebar tính năng và vùng nội dung, cùng một số thành phần dựng sẵn nằm trên nền CSS gốc của wp-admin thay vì thay thế nó.\n\nCác thành phần hiện có:\n\n- Bố cục chính. Sidebar tính năng, thanh tiêu đề cố định với nút Save, footer hiện version và link hỗ trợ.\n- Danh sách cài đặt theo nhóm. Mỗi dòng có nhãn, mô tả ngắn và control bên phải, kèm chấm trạng thái và một vùng riêng cho thao tác xóa.\n- Control nhập liệu. Toggle, nhóm chọn nhiều dạng pill, chọn màu và chọn file từ Media Library.\n- Phản hồi. Notice, thanh tiến trình, meter gọn trong một dòng và spinner.\n\nCùng một bố cục ở hai plugin khác nhau: Perxel Image Optimizer (trái) và Perxel AI Translate (phải).\n\nBộ giao diện được vendor vào từng plugin tại vendor/perxel-ui/, theo cùng mô hình với Action Scheduler: commit vào repo plugin, đóng gói trong file zip, cập nhật bằng một script. Trình nạp lúc chạy luôn chọn bản version cao nhất trong số các plugin đang kích hoạt, nên một bản cũ trong plugin này không thể làm hỏng hay đổi giao diện của plugin khác.\n\nTrong cùng một major version, API của bộ giao diện chỉ thêm chứ không bớt. Vì vậy, plugin cũ dùng bản kit mới hay plugin mới dùng bản kit cũ đều không gây lỗi; nếu plugin cần bản mới hơn bản đang chạy, trang quản trị chỉ hiện một thông báo.\n\nĐã qua vòng duyệt của WordPress.org\n\nMỗi plugin gửi lên WordPress.org đều được team Plugin Review đọc mã nguồn trước khi duyệt, chủ yếu về bảo mật và chuẩn viết code của WordPress. Các plugin dựng trên toolkit này đã được duyệt:\n\n- Perxel Image Optimizer. Chuyển ảnh WordPress sang WebP ngay trên server.\n- Perxel AI Translate. Dịch bài viết WPML bằng AI qua OpenRouter.\n- Perxel Accordion for TinyMCE. Thêm nút tạo accordion vào Classic Editor.\n\nCác góp ý của team review được sửa luôn trong toolkit, nên plugin nào dựng sau này, kể cả custom plugin làm cho khách hàng, cũng bắt đầu từ cùng một chuẩn đó.\n\nMột nền chung cho mọi plugin\n\nBộ toolkit rút ngắn thời gian khởi tạo một plugin mới và giữ cho toàn bộ danh mục plugin của Perxel thống nhất về kiến trúc backend lẫn giao diện admin. Việc nâng cấp một điểm chung được áp dụng đồng bộ cho mọi plugin qua thao tác cập nhật vendor.\n\nCả hai repo phát hành công khai trên GitHub để lập trình viên và agency tham khảo hoặc dùng làm bộ khung cho dự án của mình. Bộ toolkit này là nền cho dịch vụ lập trình custom plugin (/services/wordpress-plugins) tại Perxel.\n\n1. wp-plugin-starter\n2. wp-plugin-ui\n3. Action Scheduler\n4. Perxel Image Optimizer trên WordPress.org\n5. Perxel AI Translate trên WordPress.org\n6. Perxel Accordion for TinyMCE trên WordPress.org"},{"kind":"product","locale":"en","slug":"spotlight","title":"Spotlight","shortTitle":null,"excerpt":"A search box for your website, like Spotlight on a Mac. Visitors find any page as they type, ask a question and get an answer from your own content, or reach your contact form, all from one place.","categories":["Open source"],"tech":[{"id":"react","label":"React"}],"date":"2026-10-13","updated":null,"dateModified":"2026-10-13","url":"https://perxel.com/en/products/spotlight","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Open source","title":"View on GitHub","href":"https://github.com/perxel/perxel-spotlight"}],"productType":"ai-product","body":"Spotlight gives your website one box for everything a visitor came to do. They press ⌘K or the button in the header, and pages appear as they type. If they don't find what they need, they press Enter and an AI answers from your own content, then shows the pages it used. Ask Perxel on this site runs on Spotlight.\n\nWhy one box\n\nMost websites have a chat bubble in one corner and a search box somewhere else, and visitors have to guess which one to use. Often they use neither and leave. With Spotlight there is one obvious place to start, on every page.\n\nWhat your visitors get\n\n- Pages as they type. Results show with every letter, and the typed words are highlighted so it's clear why each one matched. Vietnamese works typed with or without accents.\n- Answers from your content, at any hour. The AI answers only from what your website says, and lists the pages behind each answer so visitors can read more.\n- Your contact form, one word away. Typing \"contact\" opens the form directly. After a conversation, the AI can fill in the form from what the visitor asked. The visitor still decides whether to send it.\n- The same experience on phones. A button in the bottom bar opens the box, and the results are sized for a thumb.\n\nOn a phone, the Ask Perxel button in the bottom bar opens the box.\n\nWhat your business gets\n\n- No slower website. Spotlight loads only when someone opens it, so your pages load as fast as before.\n- Protection from abuse. Every question passes a bot check, each visitor can only ask so often, and a daily cap keeps AI costs in check.\n- Visitors reach what they need faster. They don't have to work out your menu: they type what they want, and get the page or an answer.\n\nGetting Spotlight on your website\n\nWe set up Spotlight for you: we choose what it searches, connect the AI to your content, design it to your brand and test it on desktop and phones. We can also run it for you. The AI and hosting accounts sit with us, and we keep an eye on usage and costs, so you have no extra accounts to manage. Spotlight is open source, so the code stays with your website. It also runs on phucbm.com. Developers can find it on GitHub.\n\nTalk to us about adding Spotlight to your website (/en/contact)\n\n1. perxel-spotlight on GitHub"},{"kind":"product","locale":"en","slug":"perxel-social-kit","title":"Perxel Social Kit","shortTitle":null,"excerpt":"An open-source tool that makes social images and short videos from React templates: write a post once and the kit renders it square, 16:9 and 9:16. It also makes the images and clips for a site's blog posts from a recipe file.","categories":["Open source"],"tech":[{"id":"react","label":"React"}],"date":"2026-10-12","updated":null,"dateModified":"2026-10-12","url":"https://perxel.com/en/products/perxel-social-kit","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Open source","title":"View on GitHub","href":"https://github.com/perxel/perxel-social-kit"}],"productType":"tool","body":"Perxel Social Kit is an open-source toolkit that lets an AI agent make social images and short videos. You describe the post to your agent (Claude Code, Cursor or another), and the agent uses the kit to render it as a 1:1 square, a 16:9 landscape and a 9:16 portrait image (or video), then reviews every size itself before showing you the result. Templates are React components in your own repo, so the images carry your brand, not ours.\n\nThe problem\n\nEvery post needs the same content in several sizes: square for LinkedIn, landscape for X and the website, portrait for Stories, Reels and TikTok. In a design tool each size is its own file, and every text change has to be made in all of them. Portrait adds one more catch: the app's own buttons cover the top and bottom of the screen.\n\nWith Social Kit the content lives in one place and the layout for each size lives in the template. When something needs to change, you tell the agent.\n\nSetup and use\n\nRun npx @perxel/social-kit init in your project's repo. It installs the kit, creates a social/ folder with a first post and installs the skill that teaches your agent how to use the kit. From then on you just ask, for example: \"Make a launch post for our new product, in every size.\"\n\nThe skill keeps the agent to a set process: check the setup, use your project's colours, fonts and templates, render every size, then read the contact sheet and fix text that overflows or anything sitting where app buttons cover it, before it shows you anything. It never adds copy you haven't approved; it suggests it instead. To run the kit's commands yourself, see the guide on GitHub.\n\nWhat the kit does\n\n- Every size in one render. Files are named after the post (launch-square.png, launch-portrait.mp4), with a contact sheet that shows them side by side.\n- A layout for each size. Portrait can be arranged differently from landscape instead of just scaled, and keeps clear of the areas app buttons cover.\n- Short videos cut on the beat. The kit reads a track's tempo and beats, so the agent can cut on the beat. Videos are built with Remotion.\n- A whole campaign in one folder. One template can draw both the image and the video, so one post gives you every image and video of a campaign.\n- Images and clips for your site's posts. The agent can screenshot the live site, record short clips of an interaction (scrolling, typing, pressing ⌘K) and compose images from your templates. The steps are saved as a recipe, so when the design changes the agent makes them all again from it.\n\nHow we use it\n\nThe images and videos Perxel posts on social media, and most of the images in this site's posts, are made with Social Kit through an AI agent. Templates, logos and music live in the website's repo and the kit only does the rendering, so any brand change is made in the website's repo.\n\nLicence\n\nThe kit is MIT licensed, on GitHub and npm. Videos and browser templates use Remotion, which is free for individuals and companies of up to 3 people; larger companies need a Remotion licence. Plain images never need Remotion.\n\n1. perxel-social-kit on GitHub\n2. @perxel/social-kit on npm\n3. Remotion licence"},{"kind":"product","locale":"en","slug":"perxel-accordion-for-tinymce","title":"Perxel Accordion for TinyMCE","shortTitle":null,"excerpt":"An open-source plugin that adds an accordion button to the WordPress Classic Editor. Preview it in the Visual tab, show it on the frontend with accessible markup, no setup and nothing saved to the database.","categories":["WordPress Plugin","Open source"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":"2026-09-27","updated":"2026-09-29","dateModified":"2026-09-29","url":"https://perxel.com/en/products/perxel-accordion-for-tinymce","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"WordPress.org","title":"Install from the plugin directory","href":"https://wordpress.org/plugins/perxel-accordion-for-tinymce/"},{"caption":"Open source","title":"View on GitHub","href":"https://github.com/perxel/perxel-accordion-for-tinymce"}],"productType":"wordpress-plugin","body":"Perxel Accordion for TinyMCE is an open-source plugin that creates an accordion in the WordPress Classic Editor in a few clicks. The Accordion button is everywhere the Classic Editor is used: the post editor, widgets and even ACF WYSIWYG fields.\n\nBackground\n\nTo add a collapsible block such as \"Read more\" or a set of frequently asked questions in the Classic Editor, writers usually have to type HTML by hand or install a whole page builder. TinyMCE has an accordion plugin, but it only works from TinyMCE 6, while the WordPress Classic Editor still runs TinyMCE 4.\n\nPerxel Accordion for TinyMCE fills that gap with one toolbar button. There's no settings page and nothing saved to the database.\n\nCreate an accordion in the editor\n\nClick the Accordion button in the toolbar, fill in the title and content and insert it. The content area is a small Classic Editor, so you can still bold text, add links or make lists as usual.\n\nInserting an accordion from the toolbar.\n\nYou can choose the tag for the title (div, p or h1 to h6) if you want the title to be a heading in the post, and tick Open by default if you want the accordion open when the page loads.\n\nThe plugin inserts a [pxta_accordion] shortcode into the post. In the Visual tab you see the accordion just as on the frontend and click the pencil icon to edit it. In the Text tab you see the raw shortcode.\n\nOn the frontend\n\nThe accordion is built to accessibility standards and works well with a keyboard and screen readers. The plugin's CSS and JavaScript are very light and load only on pages that have an accordion.\n\nThe accordion with the default styling.\n\nIf the theme already has jQuery, the content slides smoothly open and closed. Without jQuery, or if the visitor has turned off motion on their device, it opens and closes instantly.\n\nUsing the shortcode directly\n\nThe shortcode works anywhere WordPress processes shortcodes: templates, the Shortcode block in the Block Editor or pages built with shortcodes.\n\n[pxta_accordion title=\"What does it cost?\" title_tag=\"h3\" open=\"1\"]Nothing, it's free.[/pxta_accordion]\n\nCustomising the look\n\nThe default style is tidy: a light grey background, rounded corners and an arrow on the right. To change it you have three options:\n\n- Write CSS in the theme for .pxta-accordion and .pxta-accordioncontent. An open accordion also has the class pxta-accordion--open.\n- Turn off the default CSS entirely with the pxta_accordion_load_css filter.\n- Replace all of the HTML with the pxta_accordion_html filter.\n\nInstall and requirements\n\nThe plugin is on WordPress.org. Go to Plugins, choose Add New, search for \"Perxel Accordion for TinyMCE\" and activate it. There's nothing else to set up: open a post and the Accordion button is there.\n\n- WordPress 6.5 or later, PHP 7.4 or later.\n- The Classic Editor in use, for example through the Classic Editor plugin.\n- With ACF, set the WYSIWYG field's Toolbar to Full, because the Basic toolbar doesn't allow extra buttons.\n\nWhen you remove the plugin, the shortcodes stay in your posts. They just no longer show as accordions.\n\nThe source is public on GitHub, free and with no ads. The plugin is built on WP Plugin Toolkit (/en/products/wp-plugin-toolkit) and often goes with custom plugin (/en/services/wordpress-plugins) projects at Perxel.\n\nTinyMCE is a trademark of Tiny Technologies, Inc. This plugin is independent and is not affiliated with or sponsored by Tiny Technologies, Inc.\n\n1. Perxel Accordion for TinyMCE on WordPress.org\n2. Perxel Accordion for TinyMCE on GitHub\n3. TinyMCE Accordion plugin\n4. Classic Editor on WordPress.org\n5. Advanced Custom Fields"},{"kind":"product","locale":"en","slug":"foldables","title":"Foldables","shortTitle":null,"excerpt":"A marketing website starter built to test the Next.js, Prismic and Cloudflare Workers stack on a real project, from content modelling through the CLI to preview and deploy.","categories":["Next.js","Open source"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"prismic","label":"Prismic"},{"id":"cloudflare","label":"Cloudflare"},{"id":"tailwind","label":"Tailwind CSS"}],"date":"2026-09-15","updated":null,"dateModified":"2026-09-15","url":"https://perxel.com/en/products/foldables","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Related service","title":"Next.js & Headless CMS websites","href":"/en/services/nextjs"}],"productType":"proof-of-concept","body":"Foldables is a test project researched and built by Perxel to try the full Next.js, Prismic and Cloudflare Workers stack, from content modelling through the CLI to deployment on edge infrastructure.\n\nTechnical overview\n\n- Deployment: Cloudflare Workers (edge network) through the OpenNext Cloudflare adapter, with no Vercel or Cloudflare Pages\n- Structure: 1 page type (Page) and 1 singleton (Home), demoed with 1 slice (Hero)\n- Content updates: automatic revalidation through a webhook when content is published in Prismic\n- Preview: full-website preview and Slice Simulator built into the Prismic page builder\n\nContext and goals\n\nThis is a common type of project for marketing teams: a fast, SEO-ready website with a professional editor for a non-technical team, deployed on an edge network instead of relying on the Vercel default.\n\nThe Foldables starter aims at three things at once:\n\nEvery page type and slice is managed through the Prismic CLI, with no hand-edited model JSON files, so the model stays in step between local code and the Prismic dashboard.\n\nEditors publish through the Prismic page builder and see the real layout in a separate preview pane before publishing.\n\nThe whole Next.js frontend and its route handlers run on Cloudflare Workers through OpenNext, using the edge network instead of one central server.\n\nContent management with Prismic\n\nFoldables integrates Prismic as a SaaS, managing content types and slices through the CLI instead of by hand.\n\nEditing content in the page builder, previewing each slice before publishing.\n\n- Content modelling through the CLI. Page types and slices are created and synced with npx prismic type create and npx prismic slice create, keeping the model consistent between the code and the dashboard.\n- Publishing in the page builder. Real content is created and published in the Prismic dashboard, kept separate from defining the structure.\n- Instant revalidation. A webhook listens for Prismic's publish event and triggers revalidation, so static pages update right away without rebuilding the whole site.\n\nDeployment on Cloudflare Workers\n\nVercel is the default and the most natural fit for Next.js. For Foldables, Perxel reused the OpenNext approach to run the app on Cloudflare Workers, already proven on Atlas Robotics (/en/products/atlas-robotics).\n\n- Low running cost. Cloudflare has a generous free plan, with almost no infrastructure cost at a marketing website's traffic.\n- A global edge network. Responses come from the server closest to the visitor, keeping response times short wherever they are.\n- Custom domain and its own cache. Domain and R2 cache settings are managed through Wrangler, separate from the dev environment.\n\nWhat it means for client projects\n\nFoldables is a proven starter for the Next.js and Prismic stack. When a client chooses Prismic, Perxel doesn't spend time setting up content modelling or deployment again. All the effort goes into a bespoke interface and the experience for each company.\n\nSee also the Next.js & Headless CMS website (/en/services/nextjs) service. The live demo is at foldables.perxel.com."},{"kind":"product","locale":"en","slug":"perxel-ai-translate","title":"Perxel AI Translate","shortTitle":null,"excerpt":"An open-source WPML AI translation plugin that bulk-translates WordPress posts into your WPML languages with the AI model you choose through OpenRouter. You pay OpenRouter directly, not WPML credits, and see the cost before you run.","categories":["WordPress Plugin","Open source"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"wpml","label":"WPML"},{"id":"openrouter","label":"OpenRouter"},{"id":"gemini","label":"Gemini"}],"date":"2026-09-01","updated":"2026-09-27","dateModified":"2026-09-27","url":"https://perxel.com/en/products/perxel-ai-translate","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"WordPress.org","title":"Install from the plugin directory","href":"https://wordpress.org/plugins/perxel-ai-translate/"},{"caption":"Open source","title":"View on GitHub","href":"https://github.com/perxel/wp-ai-translate"}],"productType":"wordpress-plugin","body":"Perxel AI Translate is an open-source WPML AI translation plugin. It translates posts, pages and custom post types into the languages installed in WPML. The plugin sends content to the AI model you choose through OpenRouter, then writes the result straight into WordPress as a WPML translation. It came out of the Khatra Tile project (/en/works/khatra), which needed about 1,000 posts and products translated into English.\n\nBackground\n\nWPML has automatic translation built in, but it charges by credit. The more content a site has, the higher the cost, and you can't choose which model translates. Perxel AI Translate uses your own OpenRouter API key: you pick the model and pay OpenRouter directly, with no credits to buy from anyone else.\n\nBulk-translate WPML posts with AI\n\nIn the post list, select the posts to translate and choose Perxel AI Translate… in Bulk actions. When editing a single post, click Translate this page in the toolbar.\n\nThe Translation screen: choose the target languages and the data to translate, and see the word and cost estimate before running.\n\nClick Translate and apply to start. You can close the tab at any time, then reopen the run and click Resume to continue. If a post fails, you retry just that post, and translations already done are reused, so you don't pay for model calls twice. Every run is saved under Tools → AI Translate → History.\n\nThe History screen: each run with its language, model, post count, warnings or errors, word count and cost.\n\nWhat gets translated\n\n- Main content. Title, slug, excerpt and content. HTML and page builder shortcodes such as WPBakery are kept intact, and only the text is translated.\n- Custom fields. Text, textarea and WYSIWYG fields from ACF and SCF, including fields inside Group, Repeater and Flexible Content. Other field types are copied across unchanged.\n- SEO. Title, description, focus keyword and social meta from Rank Math.\n- Taxonomies and featured images. Terms are linked to the matching WPML translation, and featured images use the WPML Media Translation version if there is one.\n\nChoose the model and control cost through OpenRouter\n\nYou can use any model on OpenRouter (Gemini, Claude, GPT and so on). The default is a low-cost Gemini Flash model. Settings checks the API key, shows how much credit the key has left and warns when the estimated cost goes over that credit. If the site's default language is Vietnamese, costs are shown in VND.\n\nThe Settings screen: API key and model, the batching option, extra instructions and the plugins it detected.\n\nExtra instructions keeps industry terms, proper names and brand voice consistent across every run. The Faster batched requests option (on by default) sends several short posts in one model call to translate faster.\n\nInstall and requirements\n\nThe plugin is on WordPress.org. After activating, go to Tools → AI Translate → Settings and enter your OpenRouter API key.\n\n- WordPress 6.2 or later, PHP 7.4 or later.\n- WPML (Multilingual CMS or higher) with at least two languages. Without WPML the plugin doesn't work.\n- An OpenRouter account and API key.\n\nTested with WPML 4.9.7, Secure Custom Fields 6.9.5, Rank Math SEO 1.0.277.2 (PRO 3.0.82) and WPBakery 9.0.1.\n\nThe source is public on GitHub. The plugin is built on WP Plugin Toolkit (/en/products/wp-plugin-toolkit) and often goes with custom plugin (/en/services/wordpress-plugins) projects at Perxel.\n\n1. Perxel AI Translate on WordPress.org\n2. Perxel AI Translate on GitHub\n3. OpenRouter\n4. WPML\n5. Rank Math\n6. Advanced Custom Fields"},{"kind":"product","locale":"en","slug":"perxel-image-optimizer","title":"Perxel Image Optimizer","shortTitle":null,"excerpt":"An open-source plugin that converts WordPress images to WebP on your own server, with no API key or third-party service. It handles bulk conversion on shared hosting and is easy to remove when you no longer need it.","categories":["WordPress Plugin","Open source"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":"2026-08-15","updated":"2026-09-22","dateModified":"2026-09-22","url":"https://perxel.com/en/products/perxel-image-optimizer","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"WordPress.org","title":"Install from the plugin directory","href":"https://wordpress.org/plugins/perxel-image-optimizer/"},{"caption":"Open source","title":"View on GitHub","href":"https://github.com/perxel/wp-image-optimizer"}],"productType":"wordpress-plugin","body":"Perxel Image Optimizer is an open-source plugin that converts images in the WordPress library to WebP. The whole conversion runs on the site's own server, with no CDN, API key or account. Your original images stay on your hosting.\n\nBackground\n\nConverting images to WebP is close to a must when optimising Core Web Vitals. But many popular plugins, such as ShortPixel and Imagify, send your images to their servers to compress them, require an account and cap the size or number of free images per month. For a site with a large media library, that is a recurring fee and one more outside system to depend on.\n\nPerxel Image Optimizer does the same job more simply: lightweight, free, converting on your server and working on shared hosting.\n\nConvert WordPress images to WebP on the server\n\nThe plugin uses the WP_Image_Editor (GD or Imagick) already on the server to create a .webp file next to the original, for example image.jpg becomes image.jpg.webp. The original is never edited or replaced.\n\nTo serve WebP to visitors, the plugin picks the method that suits the server:\n\n- Apache and LiteSpeed. A plugin-managed .htaccess block returns the .webp file when the browser sends an Accept: image/webp header. The page HTML doesn't change.\n- Nginx. When .htaccess can't be written, the plugin changes tags to when the page renders.\n\nThis option is off by default. You can turn it on or off in Settings. Turn it off and everyone gets the original images again, with no files deleted.\n\nBulk conversion on shared hosting\n\nBefore running, the Optimization screen shows what is about to happen: the number of images in the library, the number skipped for being too large, the estimated time and the settings in use. You pick the scope (the whole library or a single month) and one of two run modes.\n\nThe Optimization screen: a library of 15,040 images, estimated at about 21 minutes at most.\n\n- Background. Runs in the background with Action Scheduler, going month by month from newest to oldest and skipping images that already have a .webp. You can close the tab and it carries on. There are pause, resume and cancel buttons.\n- Fast. For shared hosting without reliable cron. The open admin tab drives the conversion, so the server runs continuously and much faster. If the host starts to struggle, the plugin pauses itself and resumes after a while. While it runs you can change the speed between Gentle, Balanced and Turbo.\n\nStopping or cancelling midway doesn't lose the files already converted. Next time the plugin carries on from where it stopped. You can also turn on an email report when it finishes, with the number of images converted, bandwidth saved, extra disk space used and any errors.\n\nCompression quality and image sizes\n\nThe Settings page is split into Conversion, Serving and Notifications.\n\nThe Settings screen: compression quality, sizes to convert, new uploads and notification email.\n\n- Quality. JPEG defaults to 80 and PNG to 90. PNG is converted losslessly, so this setting only changes file size.\n- Image sizes. Choose each size separately (full, thumbnail, medium, large and sizes added by the theme) so you don't create .webp files you won't use.\n- PNG. By default only JPEG is converted. Turn it on if you also want PNG converted.\n- Megapixel limit. Images above this threshold are skipped to avoid running out of memory. Leave it at 0 and the plugin uses a threshold based on the server's configuration (for example 16 MP).\n- New uploads. Turn on automatic optimisation so images are converted to WebP right after upload.\n\nConvert or remove WebP for a single image\n\nIn the Media Library, each image has Convert, Reconvert and Remove buttons, in both the list view and the detail panel. To convert one image again after changing the quality, or remove the WebP for just that image, you don't have to run the whole library again.\n\nUninstalling and removing WebP files\n\nSettings has a section that deletes every .webp file created and the .htaccess block added, returning the site to how it was in one step. When you delete the plugin, the options, post meta and .htaccess block are cleaned up. The .webp files are kept, so run the removal first if you want them gone too.\n\nInstall and requirements\n\nThe plugin is on WordPress.org. Go to Plugins, choose Add New, search for \"Perxel Image Optimizer\", activate it and open Media → Optimization.\n\n- PHP 7.4 or later, WordPress 6.5 or later.\n- GD or Imagick with WebP support. If it is missing, the admin stops and says so clearly.\n- Apache or LiteSpeed with a writable .htaccess so the HTML doesn't need to change. Other environments use .\n\nThe source is public on GitHub, free and with no ads. The plugin is built on WP Plugin Toolkit (/en/products/wp-plugin-toolkit) and often goes with WordPress custom theme (/en/services/wordpress-custom-theme) projects at Perxel.\n\n1. Perxel Image Optimizer on WordPress.org\n2. ShortPixel Image Optimizer on WordPress.org\n3. Imagify on WordPress.org\n4. Perxel Image Optimizer on GitHub\n5. Action Scheduler"},{"kind":"product","locale":"en","slug":"atlas-robotics","title":"Atlas Robotics","shortTitle":null,"excerpt":"A starter for B2B and technology marketing websites, built to test the Next.js, TinaCMS and Cloudflare Workers stack on a real multi-language project.","categories":["Next.js","Open source"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"},{"id":"tailwind","label":"Tailwind CSS"}],"date":"2026-08-13","updated":null,"dateModified":"2026-08-13","url":"https://perxel.com/en/products/atlas-robotics","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Insights","title":"Certified Developer by TinaCMS","href":"/en/insights/certified-tinacms-developer"}],"productType":"proof-of-concept","body":"Atlas Robotics is a test project researched and built by Perxel. The goal was a solid starter codebase (boilerplate) for B2B and technology websites, testing the Next.js, TinaCMS and Cloudflare Workers stack in a complete product that is ready for production.\n\nTechnical figures\n\n- Page response time (TTFB at the edge, measured on the demo site): < 50ms\n- Structure: 3 main collections (Products, Blog, Pages)\n- Languages: 3-language demo (EN / VI / ZH), the architecture can grow\n- Deployment: Cloudflare Workers (edge network)\n\nContext and goals\n\nThis is a common type of project for marketing teams: a fast, SEO-ready, multi-language website that is still easy to update after launch, with no extra CMS or hosting cost as the content grows.\n\nThe Atlas Robotics starter aims at three things at once:\n\nThe whole frontend is built on Next.js, with performance and Core Web Vitals handled in the architecture from the start. Responses come from the server closest to the visitor on the edge network.\n\nTinaCMS lets the editorial team edit text, images and multi-language content, and preview changes on screen before publishing.\n\nLanguages are handled in the code itself, so a new language can be added without touching the existing structure.\n\nContent management with TinaCMS\n\nAtlas Robotics integrates TinaCMS in its Git-backed mode, storing JSON and MDX files directly in the project's code.\n\nEditing text and images right on the real homepage.\n\n- Visual editing. Editors change text and images and see the result on screen (live preview) before publishing.\n- A fixed schema. Content is organised into blocks (Hero, Features, Product Catalog, Contact Form) from a schema set in advance. Unlike free-form page builders that drift from the design, the TinaCMS blocks use fixed layouts, which keeps the agreed fonts, spacing and responsive behaviour.\n- Stored in the code. All post and product data lives in the project repository, with no external database to maintain.\n\nEach page is its own Markdown file in the Pages collection, managed directly in the repository.\n\nBuilt-in multi-language structure\n\nAtlas Robotics handles languages at the architecture level, instead of relying on a third-party plugin as traditional CMSs do (WordPress usually uses WPML).\n\nContent for each language sits in its own folder: en, vi, zh.\n\n- Lower cost and better performance. A built-in i18n architecture keeps the system light, with no plugin licence fee.\n- A 3-language demo. The test build is set up in English, Vietnamese and Chinese to test the data flow and SEO-friendly URL structure (/[lang]/...).\n- Easy to extend. New languages can be added as needed without changing the existing code structure.\n\nDeployment on Cloudflare Workers\n\nVercel is the default and the most natural fit for Next.js. For Atlas Robotics, Perxel looked into running the app on Cloudflare Workers through OpenNext.\n\n- Low running cost. Cloudflare has a generous free plan. At a marketing website's traffic, under 100,000 visits a day, the site has almost no infrastructure cost.\n- A global edge network. Responses come from the server closest to the visitor, keeping response times short wherever they are.\n\nWhat it means for client projects\n\nAtlas Robotics is a proven technical starter. When Perxel builds for a client, it doesn't spend time setting up infrastructure again. All the effort goes into understanding the business requirements, designing a bespoke interface and tuning the experience for each company.\n\nResearching and standardising the Next.js and TinaCMS stack through this project is also what led to the Certified Developer badge from TinaCMS (/en/insights/certified-tinacms-developer).\n\nSee also the Next.js & Headless CMS website (/en/services/nextjs) service. The live demo is at atlas-robotics.perxel.com."},{"kind":"product","locale":"en","slug":"wp-plugin-toolkit","title":"WP Plugin Toolkit","shortTitle":null,"excerpt":"An open-source foundation for building WordPress plugins: a template repo with autoloading, standards checks in CI and a release workflow, plus a shared admin UI kit. Perxel uses it for every plugin it builds.","categories":["WordPress Plugin","Open source"],"tech":[{"id":"wordpress","label":"WordPress"}],"date":"2026-08-01","updated":"2026-10-10","dateModified":"2026-10-10","url":"https://perxel.com/en/products/wp-plugin-toolkit","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[{"caption":"Open source","title":"View on GitHub","href":"https://github.com/perxel/wp-plugin-starter"}],"productType":"tool","body":"WP Plugin Toolkit is the open-source foundation Perxel uses to build WordPress plugins. It has two parts: a template repository for the backend and a shared admin UI kit for the frontend. It is the standard base for every plugin Perxel develops, including Perxel Image Optimizer (/en/products/perxel-image-optimizer), Perxel AI Translate (/en/products/perxel-ai-translate) and Perxel Accordion for TinyMCE (/en/products/perxel-accordion-for-tinymce), all approved for the WordPress.org plugin directory.\n\nThe problem\n\nWhen you start a new plugin, most of the early time doesn't go to features but to rebuilding the scaffolding: folder structure, autoloading, activation and deactivation hooks, build setup and CI. Then comes rewriting the CSS and JS for the settings pages, and each plugin ends up a little different in layout and behaviour.\n\nWP Plugin Toolkit puts both parts into one shared starting point, so the effort goes into the business logic.\n\nThe template repository: wp-plugin-starter\n\nwp-plugin-starter is a GitHub template repository. Creating a new repo from it gives you a working plugin straight away: a codebase with a namespace and PSR-4 autoloading, a sample Settings screen rendered in the shared layout, PHPCS and WordPress Plugin Check running in CI, and a workflow that packages the install zip and releases it to WordPress.org.\n\nStarting a new plugin from the toolkit\n\nEvery step is in the repo's README, with no extra tooling:\n\n1. Create a repo from the template. On GitHub, choose Use this template and clone it.\n2. Replace the six naming tokens (namespace, display name, slug, repo name, constant prefix and hook prefix) with one sed command, then rename the main file and the .pot file. There is no build step.\n3. Add the admin UI kit if the plugin has a settings screen. Run bin/update-ui.sh with the latest wp-plugin-ui version. A plugin that only runs in the editor or through a shortcode skips this.\n4. Check and package. composer run lint runs PHPCS, composer run build writes the install zip to dist/.\n5. Release. Once WordPress.org approves the first submission, every GitHub Release deploys to WordPress.org on its own.\n\nThe admin UI kit: wp-plugin-ui\n\nwp-plugin-ui is a light admin UI layer rendered on the server with PHP and a little plain JS, with no framework and no build step. It provides a main layout with a feature sidebar and a content area, plus a few ready-made components that sit on top of wp-admin's own CSS instead of replacing it.\n\nWhat it includes today:\n\n- The main layout. A feature sidebar, a sticky title bar with the Save button, and a footer with the version and support links.\n- Grouped settings lists. Each row has a label, a short description and its control on the right, with status dots and a separate zone for destructive actions.\n- Inputs. Toggles, multi-select pills, a colour picker and a Media Library picker.\n- Feedback. Notices, a progress bar, a compact inline meter and a spinner.\n\nOne layout in two different plugins: Perxel Image Optimizer (left) and Perxel AI Translate (right).\n\nThe UI kit is vendored into each plugin at vendor/perxel-ui/, the same model as Action Scheduler: committed to the plugin repo, packaged in the zip and updated with a script. The runtime loader always picks the highest version among the active plugins, so an old copy in one plugin can't break or change the interface of another.\n\nWithin a major version the kit's API only grows, never shrinks. An old plugin running a newer kit, or a new plugin running an older one, never breaks; if a plugin needs a newer kit than the one running, it shows an admin notice.\n\nPassed WordPress.org review\n\nEvery plugin submitted to WordPress.org has its code read by the Plugin Review team before approval, mostly for security and WordPress coding standards. Plugins built on this toolkit that have been approved:\n\n- Perxel Image Optimizer. Converts WordPress images to WebP on the server.\n- Perxel AI Translate. Translates WPML posts with AI through OpenRouter.\n- Perxel Accordion for TinyMCE. Adds an accordion button to the Classic Editor.\n\nThe review team's feedback is fixed in the toolkit itself, so every plugin built later, including custom plugins for clients, starts from the same standard.\n\nOne base for every plugin\n\nThe toolkit shortens the time to start a new plugin and keeps Perxel's whole plugin catalogue consistent in both backend architecture and admin UI. An upgrade to a shared part reaches every plugin through a vendor update.\n\nBoth repos are public on GitHub so developers and agencies can read them or use them as a starter for their own projects. The toolkit is the base for Perxel's custom plugin development (/en/services/wordpress-plugins) service.\n\n1. wp-plugin-starter\n2. wp-plugin-ui\n3. Action Scheduler\n4. Perxel Image Optimizer on WordPress.org\n5. Perxel AI Translate on WordPress.org\n6. Perxel Accordion for TinyMCE on WordPress.org"}],"works":[{"kind":"work","locale":"vi","slug":"openwallet","title":"OpenWallet","shortTitle":null,"excerpt":"Web app tra cứu, so sánh và tư vấn thẻ ngân hàng tại Việt Nam. Kiến trúc nhiều lớp với Next.js, API trên Cloudflare Workers và một lớp MCP cho AI Assistant.","categories":["Fintech"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"openrouter","label":"OpenRouter"},{"id":"cloudflare","label":"Cloudflare"},{"id":"claude","label":"Claude"},{"id":"openwallet","label":"OpenWallet"},{"id":"vercel","label":"Vercel"},{"id":"langfuse","label":"Langfuse"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/works/openwallet","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"OpenWallet là một web app tra cứu, so sánh và tư vấn thẻ ngân hàng tại Việt Nam, hiện vận hành tại openwallet.vn. Dự án tích hợp AI Assistant qua giao thức MCP, cho phép các công cụ như Claude hay ChatGPT truy vấn trực tiếp dữ liệu thẻ.\n\nChỉ số kỹ thuật và tổng quan\n\n- Số lượng dữ liệu thẻ: 300+ thẻ từ 20+ ngân hàng tại Việt Nam\n- Thời gian phản hồi API (Cloudflare Workers tại Edge): < 30ms\n- Hạ tầng Frontend App: Next.js (App Router, SSR/SSG), triển khai trên Vercel\n- Hạ tầng API Layer: Hono framework trên Cloudflare Workers (api.openwallet.vn)\n- Hạ tầng MCP Layer: Model Context Protocol Server (mcp.openwallet.vn)\n- Component browser: Storybook 10 (storybook.openwallet.vn)\n- Lưu trữ dữ liệu phía client: Dexie.js (IndexedDB)\n- Đo lường và phân tích: PostHog Analytics\n\nBối cảnh và nguyên tắc vận hành\n\nThị trường thẻ tín dụng và thẻ ghi nợ tại Việt Nam rất đa dạng với hàng trăm sản phẩm cùng các điều khoản phức tạp về phí thường niên, điều kiện hoàn tiền (cashback) và chương trình ưu đãi. Người tiêu dùng thường phải truy cập hàng chục trang web ngân hàng khác nhau để tự so sánh.\n\nOpenWallet được xây dựng như một công cụ tra cứu, so sánh và tư vấn độc lập. Điểm cốt lõi trong mô hình của OpenWallet là tính trung lập về nội dung: thuật toán xếp hạng và gợi ý thẻ hoạt động khách quan, không bị chi phối bởi quan hệ thương mại hay tài trợ từ bất kỳ ngân hàng nào.\n\nKiến trúc mã nguồn nhiều lớp\n\nĐể xử lý khối lượng dữ liệu lớn, đảm bảo tốc độ truy xuất nhanh và sẵn sàng kết nối với các mô hình ngôn ngữ lớn (LLM), OpenWallet được phân tách thành ba lớp chuyên biệt.\n\nLớp giao diện (Frontend App)\n\nXây dựng trên Next.js và Tailwind CSS v4, triển khai trên Vercel. Cơ chế render kết hợp Server-Side Rendering (SSR) và Static Site Generation (SSG) cho các trang chi tiết thẻ, tối ưu SEO và nạp dữ liệu ngay từ bước build. Dữ liệu tra cứu được lưu một phần ở bộ nhớ trình duyệt qua Dexie.js (IndexedDB), giúp thao tác lọc và so sánh diễn ra ngay lập tức mà không cần gọi lại server liên tục.\n\nLớp dữ liệu (API Layer)\n\nTách biệt hoàn toàn khỏi ứng dụng web chính, giao tiếp qua địa chỉ api.openwallet.vn. Xây dựng bằng Hono framework chạy trực tiếp trên Cloudflare Workers ở mạng lưới Edge, cung cấp dữ liệu thẻ dạng JSON với độ trễ thấp, khả năng chịu tải cao và chi phí vận hành hạ tầng tối ưu.\n\nLớp giao tiếp AI (MCP Layer)\n\nLớp giao thức Model Context Protocol xây dựng trực tiếp trên Lớp API, vận hành tại mcp.openwallet.vn. Lớp này cung cấp giao diện dữ liệu có cấu trúc dành riêng cho các mô hình AI đọc và truy xuất. Ứng dụng thực tế gồm hai hướng: tích hợp trực tiếp vào Owie Chat (trợ lý AI tư vấn thẻ ngay trên website), và cho phép các AI Assistant bên ngoài như Claude Desktop hay ChatGPT kết nối thẳng vào cơ sở dữ liệu của OpenWallet để trả lời câu hỏi của người dùng dựa trên dữ liệu thực tế.\n\nBộ tính năng cốt lõi\n\n- Card Directory. Tra cứu thông tin chi tiết của hơn 300 dòng thẻ từ hơn 20 ngân hàng tại Việt Nam, gồm phí thường niên, hạn mức hoàn tiền và ưu đãi mở thẻ.\n- Card Match. Người dùng nhập thói quen chi tiêu thực tế như mua sắm, du lịch, ăn uống. Thuật toán phân tích và xếp hạng các dòng thẻ phù hợp nhất.\n- Card Battle. Đặt hai thẻ bất kỳ lên bàn cân để so sánh trực diện về chi phí, tỷ lệ hoàn tiền và điều kiện áp dụng.\n- Owie Chat. Trợ lý AI trả lời các thắc mắc về thẻ ngân hàng dựa trên dữ liệu từ OpenWallet, sử dụng miễn phí và không yêu cầu đăng ký tài khoản.\n- OpenWallet MCP Integration. Cho phép người dùng nâng cao tích hợp dữ liệu OpenWallet vào các công cụ AI cá nhân.\n\nChuẩn hóa giao diện với Storybook\n\nĐể đảm bảo tính nhất quán về thiết kế và tiết kiệm thời gian phát triển tính năng mới, dự án xây dựng hệ thống component library qua Storybook 10 (storybook.openwallet.vn). Các file câu chuyện (*.stories.tsx) được đặt ngay bên cạnh mã nguồn của từng component, giúp team lập trình kiểm thử độc lập giao diện của từng nút bấm, thẻ thông tin hay biểu đồ so sánh trên nhiều trạng thái dữ liệu trước khi ghép vào trang chính thức.\n\nKết quả\n\nOpenWallet cho thấy cách kết hợp kiến trúc web hiện đại với Next.js, hạ tầng Edge API trên Cloudflare Workers và giao thức MCP để giải quyết một bài toán dữ liệu thực tế cho người tiêu dùng Việt Nam. Dự án thể hiện năng lực của Perxel khi xây dựng các hệ thống ứng dụng web nhiều lớp, có khả năng mở rộng và sẵn sàng tích hợp với công cụ AI. Stack Cloudflare Workers tại Edge cũng được Perxel dùng lại cho Atlas Robotics (/products/atlas-robotics).\n\n1. OpenWallet\n2. Model Context Protocol"},{"kind":"work","locale":"vi","slug":"khatra","title":"Khatra Tile","shortTitle":null,"excerpt":"Tái cấu trúc, thiết kế lại và mở rộng hệ thống website hơn 10 năm tuổi của một doanh nghiệp gạch ốp lát, trên WordPress và các custom plugin. Chuẩn hóa gần 800 sản phẩm, hơn 14.000 hình ảnh và giữ nguyên cấu trúc SEO.","categories":["Corporate"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"wpbakery","label":"WPBakery"},{"id":"threejs","label":"Three.js"},{"id":"gsap","label":"GSAP"},{"id":"wpml","label":"WPML"},{"id":"openrouter","label":"OpenRouter"},{"id":"gemini","label":"Gemini"},{"id":"pagespeed","label":"PageSpeed Insights"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/works/khatra","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[{"kind":"insight","slug":"seo-score"},{"kind":"insight","slug":"geo"},{"kind":"insight","slug":"pagespeed"}],"links":[{"caption":"Website","title":"Xem khatra.com.vn","href":"https://khatra.com.vn/"}],"externalUrl":"https://khatra.com.vn/","industries":["Retail"],"body":"Khatra Tile là một doanh nghiệp lâu năm trong ngành gạch ốp lát tại Việt Nam, sở hữu tệp khách hàng gồm nhiều tập đoàn và doanh nghiệp lớn. Dự án được chia làm hai giai đoạn: tái cấu trúc và chuẩn hóa hệ thống trong năm 2025 (4 tháng), sau đó mở rộng tính năng module trong năm 2026 gồm Khatra Showcase (trải nghiệm 2D và 3D) và Perxel AI Translate.\n\nBối cảnh và bài toán tái kiến trúc\n\nChủ doanh nghiệp là người am hiểu kỹ thuật, đã tự tay xây dựng và trực tiếp vận hành hệ thống website trong nhiều năm. Việc duy trì một website doanh nghiệp hơn 10 năm, tích lũy kho dữ liệu lớn và giữ vững vị trí Top 1 SEO ngành gạch trong thời gian dài là một thành tựu đáng ghi nhận từ phía khách hàng.\n\nSau hơn 10 năm vận hành, website tích tụ gần 800 sản phẩm, hơn 14.000 hình ảnh cùng nhiều chuỗi mã rác (hardcoded strings) sinh ra bởi các page builder thế hệ cũ. Khi khối lượng dữ liệu vượt ngưỡng, hệ thống chưa được tối ưu về kiến trúc bắt đầu xuất hiện nhiều vấn đề: trang quản trị load chậm, tốc độ tải trang phía người dùng giảm và việc bổ sung tính năng mới trở nên phức tạp.\n\nMục tiêu tái cấu trúc năm 2025:\n\n- Tái thiết kế và tái lập trình. Thực thi bản vẽ trên WordPress và WPBakery, đồng dạng với hệ thống cũ để giữ thói quen thao tác của khách hàng, nhưng toàn bộ mã nguồn theme được viết mới hoàn toàn.\n- Giữ nguyên cấu trúc SEO. Bảo toàn cấu trúc đường dẫn (URL) và duy trì thứ hạng SEO của ngành gạch.\n\nGiao diện mới của Khatra Tile trên desktop, tablet và mobile.\n\nChuẩn hóa dữ liệu và tối ưu hạ tầng (giai đoạn 1, năm 2025)\n\n- Tự động hóa làm sạch dữ liệu bằng AI. Perxel dùng công cụ AI để quét và chuyển đổi hàng loạt nội dung của gần 800 sản phẩm sang định dạng mới, loại bỏ các chuỗi hardcode dư thừa do page builder cũ tạo ra mà giữ nguyên nội dung, cấu trúc văn bản và hình ảnh gốc.\n- Tối ưu kho hơn 14.000 hình ảnh. Nén và chuẩn hóa lại toàn bộ kho ảnh tích lũy hơn 10 năm, giảm dung lượng lưu trữ mà vẫn giữ độ nét chi tiết bề mặt gạch.\n- Tư vấn tối ưu chi phí hosting. Perxel tư vấn Khatra Tile chọn giải pháp hạ tầng hosting phù hợp với quy mô thực tế của website, loại bỏ các gói tài nguyên dư thừa và giảm chi phí vận hành hàng tháng.\n\nKết quả sau 4 tháng: trang quản trị load nhanh hơn, thao tác cập nhật bài viết và quản lý sản phẩm mượt hơn. Thứ hạng SEO và các từ khóa quan trọng trong ngành gạch được giữ ổn định. Về tốc độ, dữ liệu người dùng thật (CrUX) của cả domain đạt Core Web Vitals trên mobile: LCP 2,2 giây, INP 95 ms, CLS 0,02 (PageSpeed Insights, ngày 10/10/2026). Điểm lab bản mobile chỉ là 73, và lý do hai con số chênh nhau được giải thích trong bài PageSpeed Insights & Core Web Vitals (/insights/pagespeed). Trên mobile vẫn còn chỗ cải thiện: ảnh banner được script thay vào sau khi trang tải, và khoảng 10 ảnh trong slider cùng được đánh dấu ưu tiên tải cao.\n\nPhần trên là dữ liệu người dùng thật của cả domain (đạt), phần dưới là một lượt đo lab (73 điểm).\n\nMở rộng tính năng và module hóa (giai đoạn 2, năm 2026)\n\nNhờ bộ codebase được quy hoạch tinh gọn từ năm 2025, việc bổ sung các tính năng nâng cao trong năm 2026 diễn ra thuận lợi. Cả hai tính năng dưới đây đều được đóng gói dưới dạng custom plugin (/services/wordpress-plugins) độc lập.\n\nPlugin \"Khatra Showcase\" (trải nghiệm 2D và 3D)\n\n- 3D native. Từ gallery sản phẩm, người xem mở trình xem 3D để thấy viên gạch với texture thật dưới ánh sáng, rồi chuyển giữa góc chính diện, cận chi tiết và cạnh bên để thấy độ dày và cạnh vát. Perxel phát triển trình hiển thị 3D bằng Three.js thay vì nhúng trình xem 3D từ bên thứ ba. Nhờ đó giao diện 3D đồng bộ hoàn toàn với UI hiện có của website và không kéo theo mã nguồn dư thừa.\n- Module hóa. Toàn bộ tính năng tương tác ảnh 2D (GSAP) và xem sản phẩm 3D được đóng gói độc lập trong plugin Khatra Showcase. Khách hàng có thể cài đặt hoặc gỡ bỏ bất kỳ lúc nào mà không ảnh hưởng đến các chức năng cốt lõi.\n\nBấm Xem 3D trên trang sản phẩm, trình xem mở viên gạch ở góc chính diện, sau đó chuyển sang góc cận chi tiết và cạnh bên.\n\nPlugin \"Perxel AI Translate\" (dịch thuật quy mô lớn)\n\nBài toán là bổ sung phiên bản tiếng Anh cho gần 1.000 bài viết (800 sản phẩm, bài viết dự án, trang SEO, blog), tổng khối lượng khoảng 2,8 triệu từ.\n\n- Giải pháp. Perxel xây dựng một plugin dịch thuật riêng theo tư duy module hóa, có thể tái sử dụng cho các dự án WordPress khác, Plugin gửi nội dung tới model Gemini 3.7 Flash qua OpenRouter, nên có thể đổi sang model khác khi cần. Sau dự án, plugin được phát hành mã nguồn mở với tên Perxel AI Translate (/products/perxel-ai-translate).\n- Thực thi. Thao tác dịch tự động toàn bộ 2,8 triệu từ chỉ qua hai cú click trên giao diện và hoàn tất trong một ngày xử lý.\n- Chi phí. Tổng chi phí API cho 2,8 triệu từ khoảng 200.000 VNĐ. Theo tính toán chi phí của dự án, con số này rẻ hơn khoảng 600 lần so với việc mua credit AI của plugin WPML cho cùng dung lượng.\n\nTrước khi chạy, plugin ước tính số từ và chi phí của từng bài.\n\nKết quả\n\nCase study Khatra Tile cho thấy cách Perxel xử lý các hệ thống web có quy mô dữ liệu lớn: tôn trọng cấu trúc SEO và thói quen quản trị đã hình thành trong hơn 10 năm, chọn giải pháp hosting hợp lý, giải quyết các nghẽn kỹ thuật ở gốc để việc mở rộng tính năng về sau diễn ra nhanh, và đóng gói công cụ AI thành các module hữu ích cho việc làm sạch dữ liệu và dịch thuật quy mô lớn. Nền tảng của cả dự án là một WordPress custom theme (/services/wordpress-custom-theme) viết mới, và cách Perxel chọn lọc plugin đi kèm được nêu trong ghi chú về plugin WordPress (/insights/wordpress-plugin-list)."},{"kind":"work","locale":"vi","slug":"growtrics","title":"Growtrics","shortTitle":null,"excerpt":"Creative website cho một EdTech startup tại Singapore. Next.js 16 và GSAP cho phần chuyển động, TinaCMS và Google Sheets API cho hạ tầng dữ liệu tinh gọn không backend.","categories":["Startup","EdTech"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"gsap","label":"GSAP"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"},{"id":"vercel","label":"Vercel"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/works/growtrics","visibility":"public","deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[],"industries":["Education","Technology"],"body":"Growtrics là một EdTech startup hướng tới thị trường Singapore. Website đòi hỏi sự kết hợp giữa ngôn ngữ thương hiệu hiện đại, nội dung giáo dục và các hiệu ứng chuyển động mượt mà. Dự án do Phúc Bùi (phucbm) đảm nhận phát triển kỹ thuật độc lập dưới dạng freelance, trước khi thành lập Perxel.\n\nChỉ số kỹ thuật và tổng quan\n\n- Thị trường mục tiêu: Singapore (EdTech startup)\n- Phát triển kỹ thuật: Phúc Bùi\n- Thời gian thực hiện: 3 tháng, từ khởi tạo đến bàn giao\n- Frontend: Next.js 16 (App Router, TypeScript), Tailwind CSS, shadcn/ui\n- Chuyển động: GSAP\n- CMS: TinaCMS (Git-backed)\n- Xử lý biểu mẫu: Google Sheets API\n- Triển khai: Static Generation và client-side features trên Vercel\n\nBối cảnh dự án và quá trình bàn giao\n\nCác điểm trọng tâm trong quá trình triển khai:\n\n- Hiện thực hóa giao diện và tương tác. Chuyển bản thiết kế thành sản phẩm web thực tế, tích hợp các hiệu ứng chuyển động GSAP để tăng trải nghiệm tương tác với nội dung.\n- Kiến trúc tinh gọn không phụ thuộc database. Tối ưu chi phí vận hành cho startup bằng cách loại bỏ hoàn toàn cơ sở dữ liệu và hệ thống backend phức tạp.\n- Bàn giao cho team kỹ thuật nội bộ. Growtrics có tech team riêng, nên toàn bộ mã nguồn Next.js 16, cấu trúc TinaCMS và hệ thống component được tổ chức gọn gàng để việc tiếp quản diễn ra thuận lợi.\n\nChuyển động thị giác với GSAP và Next.js 16\n\nVới một creative website, các hiệu ứng chuyển động đóng vai trò quan trọng trong việc truyền tải tinh thần sản phẩm. Dự án dùng GSAP (/services/web-animation) kết hợp Next.js 16.\n\n- Kể chuyện qua chuyển động. Các khối nội dung, hình ảnh và chỉ số phát triển được kích hoạt chuyển động theo thao tác cuộn trang của người dùng.\n- Hiệu năng hiển thị. Dù chứa nhiều hiệu ứng, các kịch bản GSAP được tinh chỉnh để giữ tốc độ khung hình ổn định trên thiết bị di động.\n- Hệ thống UI component chuẩn hóa. Tailwind CSS kết hợp shadcn/ui giúp nhất quán cấu trúc giao diện và giữ mã nguồn dễ bảo trì.\n\nHạ tầng tinh gọn: TinaCMS và Google Sheets API\n\nĐể hệ thống vận hành nhẹ mà không phát sinh chi phí máy chủ hàng tháng, dự án áp dụng mô hình không backend, không database.\n\nQuản trị nội dung bằng TinaCMS\n\nToàn bộ nội dung bài viết và trang giới thiệu được lưu dưới dạng mã nguồn ngay trên Git repository, giúp việc biên tập và cập nhật diễn ra trực quan. Đây cũng là stack Perxel cung cấp trong dịch vụ Website Next.js & Headless CMS (/services/nextjs).\n\nThu thập biểu mẫu qua Google Sheets API\n\nThay vì dựng một database riêng chỉ để lưu danh sách đăng ký tư vấn hay nhận tin, các form trên website kết nối trực tiếp với Google Sheets API. Dữ liệu khách hàng điền trên website được đẩy thẳng về tệp Google Sheets của team Growtrics, loại bỏ chi phí lưu trữ database và giúp team vận hành tại Singapore quản lý dữ liệu trên công cụ quen thuộc.\n\nStatic Generation và triển khai trên Vercel\n\n- Tốc độ tải trang. Website dùng cơ chế Static Generation của Next.js 16. Toàn bộ các trang được biên dịch thành tệp tĩnh từ quá trình build, cho tốc độ phản hồi nhanh khi người dùng truy cập.\n- Triển khai tự động trên Vercel. Mỗi khi nội dung được xuất bản từ TinaCMS hoặc mã nguồn được cập nhật, Vercel tự động build và phân phối phiên bản mới lên CDN toàn cầu.\n\nKết quả\n\nGrowtrics kết hợp công nghệ hiển thị hiện đại (Next.js 16 và GSAP) với giải pháp dữ liệu tinh gọn (TinaCMS và Google Sheets API), mang đến cho một EdTech startup tại Singapore một website hoàn chỉnh và tối ưu chi phí vận hành. Quá trình chuyển bản vẽ lên sản phẩm thực tế bám sát cách Perxel làm việc với designer, xem thêm bàn giao thiết kế từ Figma (/insights/figma-handoff)."},{"kind":"work","locale":"vi","slug":"dta-luxury","title":"DTA Luxury","shortTitle":null,"excerpt":"Website giới thiệu dịch vụ cho một agency du lịch cao cấp tại thị trường Úc. Hiện thực trên WordPress bằng Gutenberg block editor thuần, không page builder.","categories":["Tourism"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"gutenberg","label":"Gutenberg"},{"id":"gsap","label":"GSAP"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/works/dta-luxury","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"externalUrl":"https://dtaluxury.au/","industries":["Tourism"],"body":"DTA Luxury là một agency chuyên cung cấp dịch vụ du lịch cao cấp tại thị trường Úc, hướng tới tệp khách hàng đòi hỏi sự chỉn chu về hình ảnh, thông tin minh bạch và trải nghiệm duyệt web cao cấp. Bản thiết kế tập trung vào tinh thần tối giản, bố cục thoáng và tôn vinh hình ảnh điểm đến.\n\nTổng quan dự án\n\n- Lĩnh vực: Dịch vụ du lịch và lữ hành cao cấp\n- Thị trường: Úc\n- Phát triển kỹ thuật: Perxel\n- Nền tảng CMS: WordPress\n- Giải pháp builder: Gutenberg block editor thuần (native WordPress blocks)\n- Tối ưu mã nguồn: Custom theme nhẹ, không phụ thuộc page builder bên thứ ba\n\nĐịnh hướng thiết kế và nhiệm vụ kỹ thuật\n\nPerxel hiện thực hóa bản thiết kế lên WordPress với bộ mã nguồn tinh gọn, đồng thời chủ động trao đổi cùng designer về các responsive edge case và cách cấu trúc block để team DTA Luxury có được các layout tái sử dụng sau bàn giao. Quá trình chuyển giao từ Figma sang giao diện production tuân theo cách Perxel làm việc với designer, xem thêm bàn giao thiết kế từ Figma (/insights/figma-handoff).\n\nGiải pháp: Gutenberg block editor thuần\n\nĐể duy trì tốc độ tải trang và mang lại trải nghiệm quản trị lâu dài, Perxel phát triển giao diện dựa trên Gutenberg thuần (WordPress native block editor).\n\nLoại bỏ các page builder nặng\n\nThay vì dùng các plugin dựng trang phình to như Elementor hay WPBakery (vốn tạo nhiều mã thừa và làm chậm tốc độ tải trang), Perxel xây dựng giao diện hoàn toàn bằng hệ thống block gốc của WordPress.\n\n- Tốc độ. Loại bỏ mã CSS và JS dư thừa, giúp trang web giữ hiệu năng tải mượt mà.\n- Mã nguồn sạch. Tuân thủ tiêu chuẩn lập trình gốc của WordPress, an toàn và dễ cập nhật lên các phiên bản sau.\n\nTự do quản trị nội dung\n\nBằng việc chuyển các phần thiết kế thành các Gutenberg block chuẩn hóa, team vận hành DTA Luxury có thể chỉnh sửa văn bản, thay đổi hình ảnh hành trình hay bổ sung các gói tour mới ngay trong trình biên tập gốc. Toàn bộ font chữ, khoảng cách và màu sắc được cố định theo quy chuẩn thiết kế ban đầu, giúp nội dung mới luôn đồng bộ về nhận diện thương hiệu.\n\nKết quả\n\nDTA Luxury là một dự án điển hình cho mô hình website giới thiệu dịch vụ tối giản, chỉn chu và dễ vận hành. Sự kết hợp giữa tư duy thiết kế tối giản và giải pháp Gutenberg thuần từ Perxel mang đến cho DTA Luxury một trang web du lịch mượt mà và dễ quản trị. Đây cũng là cách tiếp cận trong dịch vụ làm website WordPress (/services/wordpress-custom-theme) của Perxel."},{"kind":"work","locale":"vi","slug":"perxel-website","title":"Website Perxel 2026","shortTitle":"Website Perxel","excerpt":"Perxel làm lại website của mình bằng Next.js, GSAP và Cloudflare Workers: nước dâng, cá voi vẽ bằng code, máy bay giấy tự gấp trên canvas. Bài viết chia sẻ cách làm, những ý tưởng đã bỏ, kết quả đo tốc độ và nguồn các tài nguyên đã sử dụng.","categories":["Studio"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"gsap","label":"GSAP"},{"id":"tailwind","label":"Tailwind CSS"},{"id":"cloudflare","label":"Cloudflare"},{"id":"github","label":"GitHub"},{"id":"lottie","label":"Lottie"}],"date":"2026-10-09","updated":null,"dateModified":"2026-10-09","url":"https://perxel.com/works/perxel-website","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[{"kind":"insight","slug":"seo-score"},{"kind":"insight","slug":"geo"},{"kind":"insight","slug":"brevo-newsletter"},{"kind":"insight","slug":"nextjs-performance"},{"kind":"insight","slug":"pagespeed"}],"links":[],"body":"Website Perxel 2026 là phiên bản mới của website Perxel, được làm lại toàn bộ bằng Next.js, GSAP và Cloudflare Workers. Trang chủ có nước dâng lên che màn hình, một con cá voi bơi đi mất, và một chiếc máy bay giấy tự gấp lại ở cuối trang. Cả site xoay quanh ba thứ: nước, bay và một nhân vật làm con trỏ. Bài viết này chia sẻ cách Perxel làm từng phần, những ý tưởng đã thử rồi bỏ, cách đo tốc độ, và ghi nguồn những tài nguyên không do Perxel tạo ra.\n\nĐề bài\n\nPerxel làm website cho designer và agency, nên website của Perxel cũng là sản phẩm đầu tiên khách hàng nhìn vào. Nguyên tắc đặt ra từ đầu là toàn bộ site giữ phong cách gọn: nền trắng, chữ nhẹ, nút bấm đơn giản. Riêng trang chủ có nhiều hiệu ứng hơn, vì đây là nơi thể hiện rõ nhất khả năng làm animation của Perxel.\n\nÝ tưởng xuyên suốt của site là nước, bay và một nhân vật có tính cách. Nước là chất liệu: mép nước, bình nước, biển và con cá voi. Bay là chuyển động: chiếc máy bay giấy lượn vòng rồi hạ cánh, con cá voi lướt đi xa dần, các card bơi qua màn hình như một đàn cá. Nhân vật là con trỏ, một giọt nước có hai mắt đi theo bạn qua mọi trang. Ba thứ này nối các phần của trang chủ thành một câu chuyện liền mạch, thay vì một chuỗi hiệu ứng rời nhau.\n\nMột yêu cầu khác là animation không được làm chậm tốc độ tải trang. Trang chủ đẹp nhưng phải chờ vài giây mới hiện chữ đầu tiên thì người xem cũng khó đánh giá cao. Bản đầu tiên của trang chủ mắc đúng lỗi này. Phần \"Giữ tốc độ\" bên dưới kể lại cách sửa.\n\nStack\n\n- Next.js 16 (App Router) và React 19 cho toàn bộ site, các bài viết được soạn bằng MDX.\n- Tailwind CSS 4 cho giao diện.\n- GSAP (ScrollTrigger) và Lenis cho scroll: pin màn hình, scrub theo cuộn, cuộn mượt.\n- Canvas cho các hiệu ứng nặng hình ảnh (nước, cá voi, máy bay giấy, con trỏ). Vẽ bằng code nên hình luôn nét ở mọi kích thước và kiểm soát được từng frame.\n- Cloudflare Workers để chạy site, build bằng OpenNext và deploy tự động qua GitHub Actions mỗi lần push lên main.\n\nCách làm các hiệu ứng\n\nNước dâng\n\nBên dưới tiêu đề trang chủ là một dải màu xanh brand. Các logo công nghệ rơi xuống như những viên bi và nằm trên một mép nước được vẽ bằng canvas. Khi con trỏ chạm vào, mép nước gợn sóng. Khi người dùng cuộn trang, nước dâng lên che kín màn hình, các logo nổi lên như bọt khí rồi phủ trắng toàn bộ dải màu. Màn hình trắng này cũng là nền của phần tiếp theo, nên hai phần nối liền nhau mà không có khoảng trống.\n\nNước dâng lên khi cuộn trang, các logo nổi lên rồi phủ trắng dải màu xanh.\n\nBình nước và con cá voi\n\nBa dòng chữ lớn \"With great design comes great engineering\" là ba cái bình. Khi người dùng cuộn trang, từng dòng chữ lần lượt được rót đầy nước xanh. Nước có quán tính: cuộn nhanh thì mặt nước sóng sánh hơn rồi từ từ lặng lại, và khi một dòng đầy thì có vài giọt bắn lên ở đầu chữ. Khi đã đầy, dòng chữ đung đưa nhẹ như cây thủy sinh.\n\nBa dòng chữ lần lượt được rót đầy khi cuộn trang.\n\nKhi dòng cuối đầy, nền chuyển sang biển. Một con cá voi lưng gù, nhìn từ phía sau, bơi đi xa dần. Con cá voi này được vẽ hoàn toàn bằng code, không dùng ảnh hay video. Trong suốt phần này, cá voi chỉ vẫy đuôi đúng một lần, từ lúc xuất hiện cho đến khi biến mất. Vì vậy dù người dùng cuộn nhanh hay chậm, nó vẫn bơi hết quãng đường.\n\nChữ mờ dần, rồi con cá voi bơi đi xa.\n\nĐây là phần Perxel làm lại nhiều lần nhất. Trước con cá voi, nền biển từng có cá và bong bóng kiểu hoạt hình, rồi những vệt sáng dưới nước, rồi mực loang theo con trỏ. Bản mực loang trông giống một cơn bão hơn là mặt biển, nên bị bỏ. Cách các dòng chữ rời màn hình cũng được thử nhiều kiểu: thu nhỏ, chìm xuống, tan thành bong bóng, xé ra như giấy ướt. Kiểu nào cũng trông giả, và kiểu cuối còn làm site chậm đi. Bản hiện tại đơn giản hơn: chữ mờ dần, rồi cá voi bơi đi.\n\nCon cá bơi qua các dự án\n\nỞ phần dự án nổi bật, các card không trượt thẳng mà uốn theo một làn sóng chạy từ đầu đến đuôi hàng, như một con cá đang bơi. Bản đầu dùng card phẳng xoay trong CSS 3D, nhưng card phẳng không uốn cong được nên trông không giống cá bơi. Vì vậy Perxel chuyển sang canvas: mỗi card được vẽ thành những lát dọc, lát nào cũng lệch và nghiêng theo sóng, nên ảnh, video và cả dòng tên dự án đều cong theo. Người dùng cuộn càng nhanh, hàng card uốn càng mạnh, sau đó chậm dần lại.\n\nHàng card uốn theo sóng khi cuộn trang.\n\nMáy bay giấy\n\nCuối trang chủ, một tờ giấy vuông lật vào giữa màn hình, tự gấp thành máy bay giấy, bay một vòng rồi thu nhỏ dần về đúng vị trí. Cuộn lùi thì máy bay mở ra lại. Sau khi đã gấp xong, máy bay chỉ chạy tiếp về phía trước, không mở ra nữa. Hình dạng chiếc máy bay dựa trên mô hình 3D của Trockk (xem phần Credits). Perxel dùng hình đó làm mẫu rồi vẽ lại từng nếp gấp trên canvas.\n\nTờ giấy tự gấp thành máy bay, bay một vòng rồi hạ cánh.\n\nGiọt nước làm con trỏ\n\nCon trỏ là một giọt nước có hai mắt. Trên nền xanh, nó chuyển sang màu trắng và đổi hình theo cảnh: thợ lặn, cá vàng, sứa hoặc cá nóc. Ở trang chủ, khi đứng yên một lúc nó sẽ chạy, nhảy, chơi cầu lông hoặc nhảy xuống hồ bơi. Ở các trang khác, nó không có những hành động này để người đọc không bị mất tập trung.\n\nGiữ tốc độ giữa ngần ấy chuyển động\n\nPerxel đo bằng Lighthouse và PageSpeed Insights, rồi sửa theo số đo chứ không đoán. Trên trang chủ bản mobile, LCP giảm từ 8,7 giây xuống khoảng 1,8 giây và CLS từ 0,9 về 0. Các thay đổi chia thành bốn nhóm:\n\n- Giao diện: tiêu đề hiện bằng CSS thay vì chờ GSAP, trạng thái ban đầu của layout nằm sẵn trong CSS, và điện thoại nhận phiên bản nhẹ hơn của các hiệu ứng nặng.\n- Code: mỗi trang chỉ tải JavaScript nó cần. JavaScript của trang chủ giảm từ 313 KB xuống 261 KB (brotli).\n- Tài nguyên: font được tự host và cắt theo bảng chữ tiếng Việt, ảnh và video có kích thước gần với khung hiển thị.\n- Máy chủ: một Worker nhỏ đứng trước ứng dụng Next.js trả về các trang đã prerender, để request đầu tiên không phải chờ ứng dụng khởi động.\n\nCách làm chi tiết và số đo của từng nhóm nằm trong bài Tối ưu tốc độ website Next.js (/insights/nextjs-performance).\n\nTiêu đề hiện ngay khi tải trang, nhân vật Lottie vào sau.\n\nPageSpeed Insights trên mobile, lần đo ngày 10/10/2026 (Moto G Power giả lập, mạng Slow 4G).\n\nCùng lần đo, bản desktop.\n\nHai con số trên là kết quả của một lần đo giả lập (lab data), nên đo lại có thể lệch nhiều: cùng phiên bản code này, một lần đo tối hôm trước chỉ được 68 điểm bản mobile. Con số gần với trải nghiệm thật hơn là phần \"Discover what your real users are experiencing\" ở đầu báo cáo, lấy từ dữ liệu người dùng Chrome thật trong 28 ngày. Website Perxel hiện vẫn ở trạng thái \"No Data\" vì chưa đủ lượt truy cập. Hai loại dữ liệu này khác nhau thế nào được giải thích kỹ hơn trong bài PageSpeed Insights & Core Web Vitals (/insights/pagespeed).\n\nPerxel không hứa điểm số cho website nào, kể cả website của chính mình, vì điểm phụ thuộc vào nội dung đăng lên sau đó, hosting và các bên thứ ba như analytics.\n\nHạ tầng\n\nSite chạy trên Cloudflare Workers, gói miễn phí. Perxel cảm ơn Cloudflare vì hạ tầng edge ổn định mà không tốn phí cố định hàng tháng.\n\nDeploy đi qua GitHub Actions: mỗi lần push lên main, workflow build bằng OpenNext rồi đưa lên Cloudflare. Có một chi tiết dễ vấp: Workers không có ổ đĩa, nên mọi nội dung phải được liệt kê sẵn lúc build chứ không đọc thư mục khi chạy.\n\nKhác với Vercel, Cloudflare không tự trả trang đã prerender mà không khởi động ứng dụng Next.js. Với một website ít truy cập, request đầu tiên có thể phải chờ vài giây. Perxel viết thêm một Worker nhỏ đứng trước để trả các trang này, cách làm được ghi trong phần Máy chủ của bài Tối ưu tốc độ website Next.js (/insights/nextjs-performance).\n\nCredits\n\nCác tài nguyên dưới đây không do Perxel tạo ra. Xin cảm ơn các tác giả.\n\n- Máy bay giấy ở cuối trang chủ. \"Paper Plane Asset\" của Trockk, dùng theo giấy phép Creative Commons Attribution 4.0. Mô hình này được dùng để lấy hình dạng, các nếp gấp được vẽ lại trên canvas.\n- Các animation minh hoạ (Lottie). Lấy từ LottieFiles, trong đó có artwork của Animoox. Từng file được đổi màu về bảng màu của Perxel. Cách làm xem ở bài Lottie animation (/insights/lottie-animation).\n- Cloudflare cho phần hosting, như đã nói ở trên.\n\nCâu hỏi thường gặp\n\nPerxel có làm được hiệu ứng như trang chủ cho website của khách hàng không?\n\nHiệu ứng như ở trang chủ này tốn nhiều công và chỉ phù hợp khi hiệu ứng là điểm nhấn chính của website. Perxel làm được, nhưng với đa số website marketing, vài chuyển động được chọn lọc và một codebase gọn sẽ phù hợp hơn với khách hàng. Điều này sẽ được trao đổi rõ khi bàn về dự án.\n\nCó cần GSAP và canvas cho mọi animation không?\n\nPhần lớn animation trên site này vẫn là CSS hoặc Reveal thông thường. Canvas và GSAP chỉ xuất hiện ở những chỗ CSS không làm được, như nước, cá voi hay các card uốn cong.\n\nNgười dùng tắt animation thì sao?\n\nTrình duyệt có tuỳ chọn prefers-reduced-motion. Khi bật, trang chủ không pin và không chạy các hiệu ứng nặng: các dòng chữ hiện đầy, con cá voi đứng yên ở xa, con trỏ trở về dạng mặc định. Nội dung vẫn đọc được đầy đủ.\n\nKhi tắt animation, dải công nghệ trở thành lưới logo kèm tên.\n\n1. Paper Plane Asset, Trockk (Sketchfab)\n2. Creative Commons Attribution 4.0 International\n3. Animoox trên LottieFiles"},{"kind":"work","locale":"en","slug":"openwallet","title":"OpenWallet","shortTitle":null,"excerpt":"A web app to look up, compare and get advice on bank cards in Vietnam. A layered architecture with Next.js, an API on Cloudflare Workers and an MCP layer for AI assistants.","categories":["Fintech"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"openrouter","label":"OpenRouter"},{"id":"cloudflare","label":"Cloudflare"},{"id":"claude","label":"Claude"},{"id":"openwallet","label":"OpenWallet"},{"id":"vercel","label":"Vercel"},{"id":"langfuse","label":"Langfuse"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/works/openwallet","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"OpenWallet is a web app to look up, compare and get advice on bank cards in Vietnam, live at openwallet.vn. It connects an AI assistant through the MCP protocol, so tools like Claude or ChatGPT can query the card data directly.\n\nTechnical overview\n\n- Card data: 300+ cards from 20+ banks in Vietnam\n- API response time (Cloudflare Workers at the edge): < 30ms\n- Frontend app: Next.js (App Router, SSR/SSG), deployed on Vercel\n- API layer: Hono on Cloudflare Workers (api.openwallet.vn)\n- MCP layer: Model Context Protocol server (mcp.openwallet.vn)\n- Component browser: Storybook 10 (storybook.openwallet.vn)\n- Client-side storage: Dexie.js (IndexedDB)\n- Analytics: PostHog\n\nContext and principles\n\nVietnam's credit and debit card market is wide, with hundreds of products and complicated terms for annual fees, cashback conditions and promotions. People often visit dozens of bank websites to compare cards by hand.\n\nOpenWallet is built as an independent tool to look up, compare and get advice on cards. Its core principle is neutral content: the ranking and recommendation logic works objectively and is not influenced by commercial ties or sponsorship from any bank.\n\nA layered codebase\n\nTo handle a large amount of data, keep lookups fast and be ready for large language models (LLMs), OpenWallet is split into three layers.\n\nFrontend app\n\nBuilt on Next.js and Tailwind CSS v4, deployed on Vercel. Rendering combines server-side rendering (SSR) and static site generation (SSG) for the card detail pages, which helps SEO and loads data at build time. Part of the lookup data is kept in the browser through Dexie.js (IndexedDB), so filtering and comparing happen instantly without calling the server again.\n\nAPI layer\n\nFully separate from the main web app, served at api.openwallet.vn. Built with Hono on Cloudflare Workers at the edge, it returns card data as JSON with low latency, high load capacity and low infrastructure cost.\n\nMCP layer\n\nThe Model Context Protocol layer sits directly on top of the API layer, at mcp.openwallet.vn. It gives AI models a structured data interface to read and query. It is used in two ways: built into Owie Chat (the AI assistant on the site that advises on cards), and open to external AI assistants such as Claude Desktop or ChatGPT, which can connect straight to the OpenWallet database and answer users' questions from real data.\n\nCore features\n\n- Card Directory. Detailed information on over 300 cards from more than 20 banks in Vietnam, including annual fees, cashback limits and sign-up offers.\n- Card Match. Users enter their real spending habits, such as shopping, travel and dining. The algorithm ranks the cards that fit best.\n- Card Battle. Put any two cards side by side to compare cost, cashback rate and conditions directly.\n- Owie Chat. An AI assistant that answers questions about bank cards using OpenWallet data. Free to use, with no account needed.\n- OpenWallet MCP Integration. Lets advanced users bring OpenWallet data into their own AI tools.\n\nA consistent interface with Storybook\n\nTo keep the design consistent and save time on new features, the project has a component library in Storybook 10 (storybook.openwallet.vn). The story files (*.stories.tsx) sit next to each component's source, so developers can test each button, info card or comparison chart on its own, across many data states, before it goes into a real page.\n\nOutcome\n\nOpenWallet shows how modern Next.js architecture, an edge API on Cloudflare Workers and the MCP protocol can solve a real data problem for consumers in Vietnam. It shows Perxel's ability to build layered web applications that scale and are ready to work with AI tools. The same Cloudflare Workers edge stack was reused for Atlas Robotics.\n\n1. OpenWallet\n2. Model Context Protocol"},{"kind":"work","locale":"en","slug":"khatra","title":"Khatra Tile","shortTitle":null,"excerpt":"A rebuild, redesign and extension of a website more than 10 years old for a tile company, on WordPress with custom plugins. Close to 800 products and over 14,000 images standardised, with the SEO structure kept intact.","categories":["Corporate"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"wpbakery","label":"WPBakery"},{"id":"threejs","label":"Three.js"},{"id":"gsap","label":"GSAP"},{"id":"wpml","label":"WPML"},{"id":"openrouter","label":"OpenRouter"},{"id":"gemini","label":"Gemini"},{"id":"pagespeed","label":"PageSpeed Insights"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/works/khatra","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[{"kind":"insight","slug":"seo-score"},{"kind":"insight","slug":"geo"},{"kind":"insight","slug":"pagespeed"}],"links":[{"caption":"Website","title":"Visit khatra.com.vn","href":"https://khatra.com.vn/"}],"body":"Khatra Tile is a long-established tile company in Vietnam whose clients include many large corporations. The project ran in two phases: restructuring and standardising the system in 2025 (4 months), then adding modular features in 2026, namely Khatra Showcase (a 2D and 3D experience) and Perxel AI Translate.\n\nContext and the rebuild\n\nThe owner is technically skilled and built and ran the website personally for years. Keeping a business website alive for more than 10 years, growing a large body of data and holding the number one SEO position in the tile industry for a long time is a real achievement on the client's side.\n\nAfter 10 years, the site had collected close to 800 products, over 14,000 images and a lot of hardcoded strings left behind by older page builders. Once the data passed a certain size, the architecture started to show its limits: a slow admin area, slower page loads for visitors and new features that were hard to add.\n\nGoals of the 2025 rebuild:\n\n- Redesign and rebuild. The new design was built on WordPress and WPBakery, matching the old system so the client could keep their editing habits, with the theme code written from scratch.\n- Keep the SEO structure. URL structure preserved, so the site's search rankings in the tile industry stayed in place.\n\nThe new Khatra Tile site on desktop, tablet and mobile.\n\nData cleanup and infrastructure (phase 1, 2025)\n\n- AI-assisted data cleanup. Perxel used AI tooling to scan and convert the content of close to 800 products in bulk, removing the extra hardcoded strings left by the old page builder while keeping the original text, structure and images.\n- Optimising over 14,000 images. The whole image library, built up over more than 10 years, was compressed and standardised. Storage went down while the fine surface detail of the tiles stayed sharp.\n- Hosting cost advice. Perxel advised Khatra Tile on a hosting setup that fits the real size of the site, removing unused resources and cutting the monthly running cost.\n\nResult after 4 months: the admin area loads faster and updating posts and managing products is smoother. Rankings for the key tile keywords held steady. On speed, the domain's real-user data (CrUX) passes Core Web Vitals on mobile: LCP 2.2 s, INP 95 ms, CLS 0.02 (PageSpeed Insights, 10 October 2026). The mobile lab score is only 73; why the two differ is explained in PageSpeed Insights & Core Web Vitals (/en/insights/pagespeed). Mobile still has room to improve: the banner image is swapped in by a script after the page loads, and about 10 slider images are all marked as high priority.\n\nTop: real-user data for the whole domain (passed). Bottom: one lab run (73).\n\nNew features and modules (phase 2, 2026)\n\nBecause the codebase was cleaned up in 2025, adding advanced features in 2026 went smoothly. Both features below ship as standalone custom plugins (/en/services/wordpress-plugins).\n\nThe \"Khatra Showcase\" plugin (2D and 3D experience)\n\n- Native 3D. From the product gallery, visitors open a 3D viewer that shows the tile with its real texture under light, and switch between the front, a close-up and the side to see its thickness and bevelled edge. Perxel built the 3D viewer with Three.js instead of embedding a third-party viewer. The 3D interface matches the site's existing UI and adds no unnecessary code.\n- Modular. The 2D image interactions (GSAP) and the 3D product viewer are packaged inside the Khatra Showcase plugin. The client can install or remove it at any time without affecting the core features.\n\nClicking the 3D button on a product page opens the tile from the front, then moves to the close-up and side views.\n\nThe \"Perxel AI Translate\" plugin (translation at scale)\n\nThe task was to add an English version of close to 1,000 posts (800 products, project posts, SEO pages and blog posts), about 2.8 million words in total.\n\n- Approach. Perxel built a dedicated translation plugin as a reusable module for other WordPress projects, It sends content to Gemini 3.7 Flash through OpenRouter, so the model can be swapped when needed. After the project we released it as open source: Perxel AI Translate (/en/products/perxel-ai-translate).\n- Execution. Translating all 2.8 million words takes two clicks in the admin and finished within one day of processing.\n- Cost. The API cost for 2.8 million words was about USD 8. By the project's own calculation, that is roughly 600 times cheaper than buying AI credits from the WPML plugin for the same volume.\n\nBefore a run, the plugin estimates the words and cost of each post.\n\nOutcome\n\nKhatra Tile shows how Perxel handles web systems with a large amount of data: respecting the SEO structure and the editing habits formed over more than 10 years, choosing sensible hosting, fixing technical bottlenecks at the root so later features come faster, and packaging AI tooling into useful modules for data cleanup and large-scale translation. The base of the whole project is a freshly written WordPress custom theme (/en/services/wordpress-custom-theme)."},{"kind":"work","locale":"en","slug":"growtrics","title":"Growtrics","shortTitle":null,"excerpt":"A creative website for an EdTech startup in Singapore. Next.js 16 and GSAP for the motion, TinaCMS and the Google Sheets API for a lean data setup with no backend.","categories":["Startup","EdTech"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"gsap","label":"GSAP"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"},{"id":"vercel","label":"Vercel"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/works/growtrics","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"Growtrics is an EdTech startup serving the Singapore market. The website had to combine a modern brand language, educational content and smooth motion. The technical build was done by Perxel's lead engineer as a freelance project, before Perxel was founded.\n\nTechnical overview\n\n- Target market: Singapore (EdTech startup)\n- Technical build: Perxel's lead engineer\n- Timeline: 3 months, from kickoff to handover\n- Frontend: Next.js 16 (App Router, TypeScript), Tailwind CSS, shadcn/ui\n- Motion: GSAP\n- CMS: TinaCMS (Git-backed)\n- Form handling: Google Sheets API\n- Deployment: Static generation and client-side features on Vercel\n\nContext and handover\n\nWhat the build focused on:\n\n- Turning the design into a working interface. The design became a real website, with GSAP motion that makes the content more engaging to scroll through.\n- A lean architecture with no database. For a startup, running costs matter. The site has no database and no complex backend.\n- Handover to an in-house team. Growtrics has its own tech team, so the Next.js 16 codebase, the TinaCMS structure and the component system were organised to make the takeover easy.\n\nMotion with GSAP and Next.js 16\n\nOn a creative website, motion carries the character of the product. The project pairs GSAP (/en/services/web-animation) with Next.js 16.\n\n- Storytelling through motion. Content blocks, images and growth figures animate as the visitor scrolls.\n- Frame rate. Despite the amount of animation, the GSAP timelines are tuned to keep a steady frame rate on mobile devices.\n- A consistent UI system. Tailwind CSS and shadcn/ui keep the interface structure consistent and the codebase easy to maintain.\n\nA lean setup: TinaCMS and the Google Sheets API\n\nTo keep the system light and free of monthly server costs, the project uses no backend and no database.\n\nContent with TinaCMS\n\nAll articles and the About page are stored as code in the Git repository, so editing and updating stay visual and simple. This is also the stack Perxel offers in its Next.js and headless CMS service (/en/services/nextjs).\n\nForms through the Google Sheets API\n\nInstead of building a database just to store enquiries and newsletter sign-ups, the site's forms talk directly to the Google Sheets API. What visitors submit goes straight into a Google Sheet owned by the Growtrics team, so there is no database to host and the team in Singapore manages the data in a tool they already know.\n\nStatic generation and deployment on Vercel\n\n- Page speed. The site uses Next.js 16 static generation. Every page is compiled to a static file at build time, so pages respond quickly.\n- Automatic deploys on Vercel. When content is published from TinaCMS or the code changes, Vercel builds and ships the new version to its global CDN.\n\nOutcome\n\nGrowtrics pairs modern rendering (Next.js 16 and GSAP) with a lean data setup (TinaCMS and the Google Sheets API). The EdTech startup got a complete website with low running costs. Moving from design to production followed the way Perxel works with designers."},{"kind":"work","locale":"en","slug":"dta-luxury","title":"DTA Luxury","shortTitle":null,"excerpt":"A services website for a luxury travel agency in the Australian market. Built on WordPress with the plain Gutenberg block editor and no page builder.","categories":["Tourism"],"tech":[{"id":"wordpress","label":"WordPress"},{"id":"gutenberg","label":"Gutenberg"},{"id":"gsap","label":"GSAP"},{"id":"tailwind","label":"Tailwind CSS"}],"date":null,"updated":null,"dateModified":null,"url":"https://perxel.com/en/works/dta-luxury","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[],"body":"DTA Luxury is an agency offering luxury travel services in the Australian market, for clients who expect polished imagery, clear information and a refined browsing experience. The design is minimal, with open layouts that let the destination photography lead.\n\nProject overview\n\n- Industry: Luxury travel\n- Market: Australia\n- Technical build: Perxel\n- CMS: WordPress\n- Builder: Plain Gutenberg block editor (native WordPress blocks)\n- Code: Lightweight custom theme, no third-party page builder\n\nDesign direction and technical work\n\nPerxel built the design on WordPress with a lean codebase, and worked with the designer on responsive edge cases and on how to structure the blocks, so the DTA Luxury team ends up with reusable layouts after handover. The move from Figma to production followed the way Perxel works with designers.\n\nThe solution: plain Gutenberg\n\nTo keep pages fast and the admin pleasant over the long run, Perxel built the theme on plain Gutenberg, the native WordPress block editor.\n\nNo heavy page builders\n\nInstead of bulky page-building plugins such as Elementor or WPBakery, which add a lot of extra code and slow pages down, Perxel built the whole interface from WordPress's own block system.\n\n- Speed. No extra CSS or JS, so pages keep loading smoothly.\n- Clean code. It follows native WordPress coding standards, which keeps the site safe and easy to update to later versions.\n\nFreedom to manage content\n\nBecause the design is turned into standardised Gutenberg blocks, the DTA Luxury team can edit text, swap itinerary images and add new tour packages right in the native editor. Fonts, spacing and colours are fixed to the original design rules, so new content always matches the brand.\n\nOutcome\n\nDTA Luxury is a good example of a services website that is minimal, polished and easy to run. Pairing a minimal design approach with plain Gutenberg gave DTA Luxury a smooth travel website that is easy to manage. It is the same approach Perxel takes in its WordPress website service (/en/services/wordpress-custom-theme)."},{"kind":"work","locale":"en","slug":"perxel-website","title":"Perxel website 2026","shortTitle":"Perxel website","excerpt":"We rebuilt our own website with Next.js, GSAP and Cloudflare Workers: rising water, a whale drawn in code, a paper plane that folds itself on a canvas. Here is how we made it, the ideas we dropped, how we measured speed, and credits for the assets we used.","categories":["Studio"],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"gsap","label":"GSAP"},{"id":"tailwind","label":"Tailwind CSS"},{"id":"cloudflare","label":"Cloudflare"},{"id":"github","label":"GitHub"},{"id":"lottie","label":"Lottie"}],"date":"2026-10-09","updated":null,"dateModified":"2026-10-09","url":"https://perxel.com/en/works/perxel-website","visibility":"public","deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[{"kind":"insight","slug":"seo-score"},{"kind":"insight","slug":"geo"},{"kind":"insight","slug":"brevo-newsletter"},{"kind":"insight","slug":"nextjs-performance"},{"kind":"insight","slug":"pagespeed"}],"links":[],"body":"The Perxel 2026 website is a full rebuild of our site in Next.js, GSAP and Cloudflare Workers. On the homepage, water rises to cover the screen, a whale swims off into the deep, and a paper plane folds itself at the bottom of the page. The whole site is built around three things: water, flight and a character that plays the cursor. This post covers how we made each part, the ideas we tried and dropped, how we measured speed, and where the assets we didn't make come from.\n\nThe brief\n\nWe build websites for designers and agencies, so our own site is the first piece of work a client looks at. The rule from day one was to keep the site itself quiet: white background, light type, simple buttons. The homepage is the exception. It carries more motion, because it is where our animation work shows best.\n\nThe idea running through the site is water, flight and a character with a personality. Water is the material: the water edges, the letters that fill like bottles, the sea and the whale. Flight is the motion: the paper plane looping and landing, the whale gliding away, the project cards swimming across the screen like a fish. The character is the cursor, a water drop with two eyes that follows you through every page. Together they turn the homepage into one story instead of a string of separate effects.\n\nThe other requirement was that the animation must not slow the page down. A beautiful homepage that takes several seconds to show its first line of text is hard to admire. Our first version of the homepage made exactly that mistake. The \"Keeping it fast\" section below covers how we fixed it.\n\nStack\n\n- Next.js 16 (App Router) and React 19 for the whole site, with posts written in MDX.\n- Tailwind CSS 4 for styling.\n- GSAP (ScrollTrigger) and Lenis for scroll: pinned screens, scroll-scrubbed timelines, smooth scrolling.\n- Canvas for the image-heavy effects (water, the whale, the paper plane, the cursor). Drawn in code, they stay sharp at any size and we control every frame.\n- Cloudflare Workers to run the site, built with OpenNext and deployed by GitHub Actions on every push to main.\n\nHow the effects work\n\nRising water\n\nUnder the homepage headline sits a band of brand blue. Tech logos drop into it like marbles and rest on a water edge drawn on a canvas. Move the cursor across it and the surface ripples. As you scroll, the water rises to fill the screen, and the logos float up like bubbles until they cover the whole band in white. That white screen is also the background of the next section, so the two run into each other with no gap.\n\nThe water rises as you scroll, and the logos float up until the band turns white.\n\nBottles and a whale\n\nThe three big lines \"With great design comes great engineering\" are three bottles. As you scroll, each line fills with blue water in turn. The water has weight: scroll fast and the surface sloshes harder before it settles, and when a line is full a few droplets splash off the tops of the letters. Once full, the line sways gently like a water plant.\n\nEach line fills with water as you scroll.\n\nWhen the last line is full, the background turns into the sea. A humpback whale, seen from behind, swims away into the deep. It is drawn entirely in code, with no photo or video. Over the whole section the whale makes exactly one tail stroke, from the moment it appears to the moment it disappears. So whether you scroll fast or slow, it always swims the full distance.\n\nThe lines blur out and the whale swims off.\n\nThis is the part we rebuilt the most. Before the whale, the sea had cartoon fish and bubbles, then light patterns under the water, then ink that spread behind the cursor. The ink looked more like a storm than a sea, so it went. We also tried many ways for the lines to leave the screen: shrinking, sinking, dissolving into bubbles, tearing like wet paper. Every one of them looked fake, and the last one slowed the site down too. The current version is simpler: the letters blur out, then the whale swims away.\n\nProject cards that swim\n\nIn the featured projects section, the cards don't just slide sideways. They bend along a wave that runs from the head of the row to its tail, like a swimming fish. The first version used flat cards turned in CSS 3D, but a flat card can't bend, so it looked nothing like a fish. We moved to canvas: each card is drawn as thin vertical slices, each one shifted and sheared along the wave, so the photo, the video and even the project name bend with it. The faster you scroll, the harder the row bends, then it eases back to a slow swim.\n\nThe row of cards bends with the wave as you scroll.\n\nThe paper plane\n\nAt the end of the homepage, a square of paper flips into the middle of the screen, folds itself into a paper plane, flies one loop and shrinks into its place. Scroll back and the plane unfolds. Once it is fully folded, it only plays forward and won't unfold again. The plane's shape is based on a 3D model by Trockk (see Credits). We used it as a reference and redrew every fold on a canvas.\n\nThe sheet folds itself into a plane, flies a round and lands.\n\nA water drop for a cursor\n\nThe cursor is a water drop with two eyes. Over blue, it turns white and changes with the scene: a scuba diver, a goldfish, a jellyfish or a pufferfish. On the homepage, leave it still for a moment and it goes running, hopping, plays badminton or dives into a pool. On other pages it stays calm, so it doesn't pull attention from what you are reading.\n\nKeeping it fast with all that motion\n\nWe measured with Lighthouse and PageSpeed Insights and fixed what the numbers showed, rather than guessing. On the mobile homepage, LCP went from 8.7 seconds to about 1.8 seconds and CLS from 0.9 to 0. The changes fall into four groups:\n\n- UI: the headline shows with CSS instead of waiting for GSAP, layout starting states live in CSS, and phones get lighter versions of the heavy effects.\n- Code: each page loads only the JavaScript it needs. The homepage's JavaScript went from 313 KB to 261 KB (brotli).\n- Assets: fonts are self-hosted and cut to the Vietnamese character set, and images and videos are close to the size they're shown at.\n- Hosting: a small Worker in front of the Next.js app answers prerendered pages, so the first request doesn't wait for the app to start.\n\nHow we did each one, with the numbers, is in Next.js performance (/en/insights/nextjs-performance).\n\nThe headline shows as soon as the page loads; the Lottie character comes in after.\n\nPageSpeed Insights on mobile, run on 10 October 2026 (emulated Moto G Power, Slow 4G).\n\nThe same run on desktop.\n\nThose two numbers come from a single lab run, so running it again can move them a lot: the same build scored only 68 on mobile the evening before. The part closer to what visitors actually get is \"Discover what your real users are experiencing\" at the top of the report, built from real Chrome users over 28 days. Our site still shows \"No Data\" there because it doesn't have enough visits yet. We go into how the two differ in PageSpeed Insights & Core Web Vitals (/en/insights/pagespeed).\n\nWe don't promise a score for any website, our own included, because the score depends on the content added later, the hosting and third parties such as analytics.\n\nHosting\n\nThe site runs on Cloudflare Workers, on the free plan. Thanks to Cloudflare for a stable edge platform with no fixed monthly cost.\n\nDeploys go through GitHub Actions: every push to main builds with OpenNext and ships to Cloudflare. One detail is easy to trip on: Workers have no disk, so all content has to be listed at build time instead of read from a folder at runtime.\n\nUnlike Vercel, Cloudflare doesn't serve prerendered pages without starting the Next.js app. On a low-traffic site, the first request can wait several seconds. We wrote a small Worker that sits in front and answers those pages; how it works is in the Hosting section of Next.js performance (/en/insights/nextjs-performance).\n\nCredits\n\nWe didn't make the assets below. Thanks to their authors.\n\n- The paper plane at the end of the homepage. \"Paper Plane Asset\" by Trockk, used under Creative Commons Attribution 4.0. We used the model for its shape and redrew the folds on a canvas.\n- The illustration animations (Lottie). From LottieFiles, including artwork by Animoox. Each file was recoloured to the Perxel palette. How we did it is in our Lottie animation (/en/insights/lottie-animation) post.\n- Cloudflare for hosting, as mentioned above.\n\nFAQ\n\nCan Perxel build effects like this for a client website?\n\nEffects like the ones on this homepage take a lot of work and only make sense when the motion is the main point of the site. We can build them, but for most marketing websites a few well-chosen animations and a lean codebase serve the client better. We talk that through openly when we discuss the project.\n\nDo you need GSAP and canvas for every animation?\n\nMost of the animation on this site is still CSS or a plain Reveal entrance. Canvas and GSAP only appear where CSS can't do the job, such as the water, the whale and the bending cards.\n\nWhat happens if someone turns animation off?\n\nBrowsers have a prefers-reduced-motion setting. When it is on, the homepage doesn't pin and skips the heavy effects: the lines show already full, the whale sits still in the distance, and the cursor goes back to the default. All the content is still there to read.\n\nWith animation off, the tech band becomes a grid of logos with names.\n\n1. Paper Plane Asset, Trockk (Sketchfab)\n2. Creative Commons Attribution 4.0 International\n3. Animoox on LottieFiles"}],"projects":[{"kind":"project","locale":"vi","slug":"bab-orchids","title":"Bab Orchids","shortTitle":null,"excerpt":null,"categories":["E-commerce"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","externalUrl":"https://www.bab-orchids.com/","industries":["E-commerce"],"deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"bacha-tourism","title":"Bacha Tourism","shortTitle":null,"excerpt":null,"categories":["Tourism"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","externalUrl":"https://www.bachatourism.com/","industries":["Tourism"],"deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"the-bottle-shop","title":"The Bottle Shop","shortTitle":null,"excerpt":null,"categories":["E-commerce"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","externalUrl":"https://www.thebottleshop.asia/","industries":["E-commerce"],"deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"la-maison-chouette","title":"La Maison Chouette","shortTitle":null,"excerpt":null,"categories":["E-commerce"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","externalUrl":"https://www.lamaisonchouette.com/","industries":["E-commerce"],"deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"mia-nha-trang","title":"Mia Nha Trang","shortTitle":null,"excerpt":null,"categories":["Hospitality"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","externalUrl":"https://mianhatrang.com/","industries":["Hospitality"],"deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"tam-coc-garden","title":"Tam Coc Garden","shortTitle":null,"excerpt":null,"categories":["Hospitality"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","externalUrl":"https://www.tamcocgarden.com/","industries":["Hospitality"],"deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"toan-nguyen-architects","title":"Toan Nguyen Architects","shortTitle":null,"excerpt":null,"categories":["Architecture"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","externalUrl":"https://www.toannguyen-architects.com/","industries":["Architecture"],"deliveredByPerxel":true,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"bach-suites-saigon","title":"Bach Suites Saigon","shortTitle":null,"excerpt":null,"categories":["Hospitality"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Hospitality"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"sky-international-preschool-vietnam","title":"Sky International Preschool Vietnam","shortTitle":null,"excerpt":null,"categories":["Education"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Education"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"jones-payne","title":"Jones Payne","shortTitle":null,"excerpt":null,"categories":["Architecture"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Architecture"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"techvico","title":"Techvico","shortTitle":null,"excerpt":null,"categories":["Technology"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Technology"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"long-an-international-port","title":"Long An International Port","shortTitle":null,"excerpt":null,"categories":["Corporate"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Corporate"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"huynchi","title":"Huynchi","shortTitle":null,"excerpt":null,"categories":["Corporate"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Corporate"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"source-of-asia","title":"Source of Asia","shortTitle":null,"excerpt":null,"categories":["Corporate"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Corporate"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"tuan-loc-commodities","title":"Tuan Loc Commodities","shortTitle":null,"excerpt":null,"categories":["Corporate"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Corporate"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"rmit-experience-day-2023","title":"RMIT – Experience Day 2023","shortTitle":null,"excerpt":null,"categories":["Education"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Education"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"ree-corporation","title":"Ree Corporation","shortTitle":null,"excerpt":null,"categories":["Corporate"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Corporate"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"gilimex","title":"Gilimex","shortTitle":null,"excerpt":null,"categories":["Corporate"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Corporate"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"koru-education","title":"Koru Education","shortTitle":null,"excerpt":null,"categories":["Education"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Education"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"mia-saigon","title":"Mia Saigon","shortTitle":null,"excerpt":null,"categories":["Hospitality"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Hospitality"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"sakura-vietnam","title":"Sakura Vietnam","shortTitle":null,"excerpt":null,"categories":["E-commerce"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["E-commerce"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"food-source-international","title":"Food Source International","shortTitle":null,"excerpt":null,"categories":["Corporate"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Corporate"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"rmit-vietnam","title":"RMIT Vietnam","shortTitle":null,"excerpt":null,"categories":["Education"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Education"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"bong-bach-tuyet","title":"Bong Bach Tuyet","shortTitle":null,"excerpt":null,"categories":["Corporate"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Corporate"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"little-einstein-academy","title":"Little Einstein Academy","shortTitle":null,"excerpt":null,"categories":["Education"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Education"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"duc-khang-hospital","title":"Duc Khang Hospital","shortTitle":null,"excerpt":null,"categories":["Healthcare"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Healthcare"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]},{"kind":"project","locale":"vi","slug":"canh-dieu","title":"Canh Dieu","shortTitle":null,"excerpt":null,"categories":["Education"],"tech":[],"date":null,"updated":null,"dateModified":null,"url":null,"visibility":"portfolio-only","industries":["Education"],"deliveredByPerxel":false,"related":[],"projects":[],"usedBy":[],"links":[]}],"tech":[{"id":"nextjs","label":"Next.js"},{"id":"react","label":"React"},{"id":"motion","label":"Motion"},{"id":"gsap","label":"GSAP"},{"id":"threejs","label":"Three.js"},{"id":"webflow","label":"Webflow"},{"id":"framer","label":"Framer"},{"id":"wordpress","label":"WordPress"},{"id":"wpml","label":"WPML"},{"id":"nectarblocks","label":"NectarBlocks"},{"id":"tinacms","label":"TinaCMS"},{"id":"tinacms-certified","label":"TinaCMS Certified Developer"},{"id":"prismic","label":"Prismic"},{"id":"claude","label":"Claude"},{"id":"chatgpt","label":"ChatGPT"},{"id":"gemini","label":"Gemini"},{"id":"openrouter","label":"OpenRouter"},{"id":"figma","label":"Figma"},{"id":"github","label":"GitHub"},{"id":"cloudflare","label":"Cloudflare"},{"id":"safari","label":"Safari"},{"id":"pagespeed","label":"PageSpeed Insights"},{"id":"wpbakery","label":"WPBakery"},{"id":"gutenberg","label":"Gutenberg"},{"id":"openwallet","label":"OpenWallet"},{"id":"vercel","label":"Vercel"},{"id":"langfuse","label":"Langfuse"},{"id":"tailwind","label":"Tailwind CSS"},{"id":"lottie","label":"Lottie"},{"id":"brevo","label":"Brevo"}],"categories":{"services":[{"value":"WordPress"},{"value":"Next.js"},{"value":"Animation"},{"value":"AI"},{"value":"Tư vấn kỹ thuật"}],"insights":[{"value":"Design","description":"Ghi chú về việc chuyển design thành giao diện production chỉn chu, bám sát bản vẽ.","descriptionEn":"Notes on turning a design into a polished production interface that stays true to the original."},{"value":"Development","description":"Ghi chú về việc xây dựng website nhanh, dễ bảo trì và ổn định khi vận hành thực tế.","descriptionEn":"Notes on building websites that load fast, are easy to maintain and run reliably in production."},{"value":"CMS","description":"Ghi chú về việc chọn và tích hợp CMS để đội ngũ tự cập nhật nội dung website mà không cần lập trình viên.","descriptionEn":"Notes on choosing and integrating a CMS so your team can update the website without a developer."},{"value":"WordPress","description":"Ghi chú về việc xây dựng và vận hành website WordPress: Gutenberg, plugin và custom theme.","descriptionEn":"Notes on building and running WordPress websites: Gutenberg, plugins and custom themes."},{"value":"Performance","description":"Ghi chú về tốc độ tải trang, Core Web Vitals và cách đọc điểm PageSpeed sát với trải nghiệm thật của người dùng.","descriptionEn":"Notes on page speed, Core Web Vitals and reading PageSpeed scores the way real users experience the site."},{"value":"Animation","description":"Ghi chú về chuyển động trên website: Lottie, scroll animation và cách giữ chúng nhẹ, mượt trên nhiều thiết bị.","descriptionEn":"Notes on motion on the web: Lottie, scroll animation and keeping it light and smooth across devices."},{"value":"SEO","description":"Ghi chú về việc giúp Google và các công cụ AI như ChatGPT, Gemini đọc đúng website: SEO kỹ thuật, dữ liệu có cấu trúc và GEO.","descriptionEn":"Notes on helping Google and AI tools like ChatGPT and Gemini read a website correctly: technical SEO, structured data and GEO."},{"value":"Release","description":"Các bản phát hành mới của plugin, công cụ và sản phẩm do Perxel phát triển: có gì thay đổi, ai nên cập nhật và cập nhật thế nào.","descriptionEn":"New releases of the plugins, tools and products Perxel builds: what changed, who should update and how."}],"products":[{"value":"WordPress Plugin"},{"value":"Next.js"},{"value":"Mã nguồn mở","labelEn":"Open source","slug":"open-source"},{"value":"Mã nguồn công khai","labelEn":"Source available","slug":"source-available"},{"value":"Độc quyền","labelEn":"Exclusive","slug":"exclusive"}],"works":[{"value":"Fintech"},{"value":"Tourism"},{"value":"Startup"},{"value":"EdTech"},{"value":"Corporate"},{"value":"Studio"}]},"pricing":{"vi":{"url":"https://perxel.com/pricing","packages":[{"id":"project","services":[],"title":"Dự án trọn gói","basis":"from","price":{"vnd":20000000,"usd":1200},"unit":null,"summary":"Bắt đầu từ 20,000,000 VND ($1,200), có ngoại lệ cho các yêu cầu nhỏ, scope được xác định rõ."},{"id":"development-partner","services":["development-partner"],"title":"Đối tác phát triển","basis":"fixed","price":{"vnd":5000000,"usd":200},"unit":"block 10 giờ","summary":"5,000,000 VND ($200) / block 10 giờ, dành riêng thời gian kỹ thuật cho việc phát triển tính năng mới hoặc bảo trì liên tục."}]},"en":{"url":"https://perxel.com/en/pricing","packages":[{"id":"project","services":[],"title":"Fixed-price project","basis":"from","price":{"vnd":20000000,"usd":1200},"unit":null,"summary":"From $1,200, with exceptions for small requests with a clearly defined scope."},{"id":"development-partner","services":["development-partner"],"title":"Development partner","basis":"fixed","price":{"vnd":5000000,"usd":200},"unit":"10-hour block","summary":"$200 / 10-hour block, engineering time reserved for new features or ongoing maintenance."}]}}}