Chúng mình quản lý hệ thống nội dung ở VinID như thế nào?

Minh Nguyen
One Mount Product Design
12 min readFeb 25, 2022

Trong bài viết này, hai thành viên của đội UX Writer tại VinID — Hue Trang Luc và Minh — sẽ chia sẻ kinh nghiệm quản lý nội dung cùng các bạn

Lời nói đầu

Là một UX Writer, hẳn bạn cũng đã từng rất đau đầu về việc làm thế nào để quản lý nội dung hiệu quả và phối hợp trơn tru với các bộ phận khác. Ở VinID cũng vậy, sau 7749 lần tìm kiếm giải pháp, vận dụng và kết hợp giữa làm thủ công và các công cụ hỗ trợ & plugin hiện có trên thị trường như CMS, Figma plugin, Ditto… thì cuối cùng chúng mình đã tìm ra được phương pháp phù hợp cho những khó khăn hiện tại.

Vạn sự khởi đầu nan, gian nan bắt đầu… tìm kiếm, nghiên cứu và cải thiện tiếp.

Dù chưa hẳn là một phương pháp quản lý nội dung tốt nhất, nhưng hy vọng bài viết chia sẻ kinh nghiệm của tụi mình sẽ giúp ích được phần nào cho các bạn. Cùng theo chân bọn mình nhé!

Những khó khăn hiện tại

Đầu tiên, chúng ta hãy nói về những vấn đề đang vướng phải đã nhé. Ở VinID, chúng mình viết chữ cho nhiều phòng ban cùng lúc, và mỗi phòng ban này lại phục vụ một tập người dùng khác nhau. Do đó, cách nói chuyện và dùng từ cần có sự khác biệt nhất định để phù hợp với những người dùng này.

Tính cách của các UXW lại càng khác biệt: có bạn vui nhộn và cực kỳ sáng tạo, có bạn nghiêm túc cứng nhắc, lại có bạn trầm tính ít nói. Thành viên trong đội chúng mình còn đến từ những vùng miền khác nhau và ngồi làm ở hai đầu Tổ quốc luôn cơ. Bài toán đặt ra là làm sao để dung hòa được các tính cách này, bỏ qua cách biệt địa lý và đạt được hiệu quả mong muốn trong công việc?

Sơ sơ về con người là như vậy, thế còn về công việc thì sao? Số lượng nội dung trong 1 app là rất lớn, VinID cũng không ngoại lệ. Từ những tiêu đề, danh mục, hướng dẫn đến thông báo lỗi, tất cả đều cần đến đôi tay của đội UXW.

Số lượng các component và element trong app cũng nhiều không kém. Cùng một thông điệp nhưng khi dùng ở các component khác nhau, câu chữ sẽ phải thay đổi để tối ưu trải nghiệm người dùng mà vẫn đảm bảo được tính thẩm mỹ của app. Các bạn có thể xem ví dụ trong ảnh dưới đây, cùng 1 case mất kết nối mạng nhưng content khác hẳn hau khi đưa vào 2 component khác biệt:

Trong quá trình sử dụng, người dùng chắc chắn sẽ gặp những sự cố không mong muốn. Đây cũng là lúc đội UXW cần thể hiện sự khéo léo của mình: không chỉ trấn an và giảm bớt cảm xúc tiêu cực của người dùng, chúng mình còn cần phải đưa ra hướng dẫn giúp họ nhanh chóng giải quyết rắc rối.

Và vấn đề cuối cùng nữa: dịch thuật! Trong thời đại công nghệ 4.0 hiện nay, chúng mình cần quan tâm đến tính năng đa ngôn ngữ nữa đó. UXW không những phải giỏi Tiếng Việt, mà tiếng Anh cũng phải hay nha 🤣

Chúng mình bắt đầu đi tìm giải pháp

Crowdin là một hệ thống quản lý dịch thuật (Translation Management System — TMS) dựa trên giải pháp đám mây, thích hợp cho việc dịch các ứng dụng và trò chơi dành cho thiết bị di động một cách nhanh chóng và hiệu quả với hơn 300 ngôn ngữ. Crowdin sẽ quản lý nội dung ở dạng chuỗi string, cứ mỗi nội dung sẽ tương ứng với một chuỗi string nhất định.

Chính vì điều đó, khi so sánh với những công cụ trước đây, chúng mình nhận thấy ở Crowdin có những điểm trội về mặt quản lý hơn như sau:

  • Tất cả nội dung bên trong app đều được tập trung về một đầu mối, rất tiện để quản lý
  • Có tính đồng bộ và thống nhất
  • Dễ dàng chuẩn hóa và đối chiếu giữa các domain với nhau, tránh tình trạng lãng phí tài nguyên khi tạo string
  • Tiết kiệm thời gian, nhân lực trong việc thay đổi và cập nhật nội dung

Việc sử dụng Crowdin dường như là một bước ngoặt lớn trong việc quản lý nội dung của chúng mình lúc ấy, giải quyết dường như hầu hết các khó khăn gặp phải.

Tuy vậy, Crowdin vẫn tồn tại một vài nhược điểm chưa thể giải quyết được như chưa hỗ trợ chuyển đổi giữa các hệ điều hành chẳng hạn. Đội dev cần thực hiện thêm vài bước thủ công rồi mới có thể đưa vào hệ thống code để sử dụng.

Trong cái khó ló cái… khó 🤣🤣🤣

Hiện tại ở VinID, chúng mình sử dụng file string.xml (dành cho Android) để đẩy lên Crowdin. Chuỗi string của hệ điều hành này có dạng:

<string name=”X”>Y</string>

Trong đó: X là key và Y là value, được hiểu là nội dung mong muốn

Ví dụ: Mình có 1 đoạn description với nội dung “VinID: Siêu ứng dụng thông minh cho người Việt”, thì một chuỗi string định dạng cho hệ điều hành android sẽ là:

<string name=”description.tagline_info”>VinID: Siêu ứng dụng thông minh cho người Việt </string>

Khi đó cụm description.tagline_info là key, nội dung VinID: Siêu ứng dụng thông minh cho người Việt là value

Bắt đầu từ chỗ này, chúng mình đã gặp chút khó khăn với việc đặt tên cho chuỗi string:

  • Xuất hiện càng nhiều string cùng diễn đạt 1 value ở các domain khác nhau, gây lãng phí dung lượng app và key Crowdin
  • Mỗi thành viên UXW có cách đặt key khác nhau, xảy ra hiện tượng trùng lặp key, khiển việc quản lý trở nên khó khăn

“Bóc tách” vấn đề & hướng giải quyết

Vấn đề 1: Giảm thiểu dung lượng app và key Crowdin

Mỗi domain trên app VinID có tính chất khác nhau, tương ứng với việc nội dung sẽ được phát triển ở những tông khác nhau. Chẳng hạn khi chơi Săn Thưởng, bạn sẽ thấy nội dung triển khai tại đây được viết với giọng vui tươi, dí dỏm và hài hước, còn ở phần Ưu đãi giá sốc chủ yếu tập trung vào người dùng là các nội trợ, nội dung sẽ được biến tấu với tông điệu nhẹ nhàng, vui vẻ, đặt trọng tâm ở những lời mời chào khuyến mãi & ưu đãi.

Do tính chất khác nhau, mỗi domain sẽ được phụ trách bởi 1 squad riêng, tránh tình trạng “râu ông này cắm cằm bà kia”. Chúng mình tạo cho mỗi domain 1 file string riêng biệt để tiện theo dõi, đồng thời gom tất cả những nội dung thường xuất hiện trên toàn bộ app vào 1 file string chung là Common. Vậy là đã giải quyết xong vấn đề về dung lượng của app và key. Yay!

Common là file string chứa tất cả nội dung dùng chung, thường xuyên xuất hiện nhiều lần tại các domain. Khi đó, value của đoạn string chứa nội dung thuộc file này không được phép thay đổi nếu chưa biết rõ:

  • Có bao nhiêu vị trí trên app sử dụng nội dung này? Mỗi vị trí như vậy thuộc domain nào?
  • Nội dung thay đổi chắc chắn sẽ phù hợp với bối cảnh của những domain khác chứ?
  • Việc thay đổi có ảnh hưởng đến bố cục trên giao diện hay không? (Ví dụ: chữ có bị rớt dòng? Các component trong Design System đã có hỗ trợ cho văn bản nhiều dòng?)

Ví dụ như một từ Tất cả này xuất hiện ở rất nhiều màn hình, ở nhiều domain khác nhau:

Chính vì tính sở hữu chung này nên chúng mình luôn hết sức cẩn thận khi thay đổi bất kì value nào trong file Common. Nếu cần thay đổi, chúng mình phải thông báo cho các Product Owner, Dev và QC của tất cả các domain liên quan để họ nắm thông tin hết đó nha 😉

Vấn đề 2: Thống nhất cách đặt key

Có 2 công việc khiến chúng mình “nổ não” nhất là: Đẻ chữ & đặt tên key 🤣🤣🤣

Để có thể tận dụng tối đa những lợi ích mà Crowdin mang lại cho việc quản lý nội dung toàn app, key được tạo ra cần phải chứa các thông tin về tên domain, tên tính năng hoặc luồng trực thuộc domain, tên màn hình, tên component chứa nội dung đó và đính kèm 1 mã nhận diện do chính UXW quản lý, để đảm bảo câu chữ không bị trùng lặp nhau.

Đó là cách mà chúng mình đã thống nhất cách đặt key giữa các thành viên trong và ngoài team. Còn thông tin cụ thể hơn về cách đặt key và những lỗi thường xảy ra như: trùng key, lỗi tham số, lỗi các ký tự đặc biệt, dịch thuật,… chúng mình xin hẹn chia sẻ với các bạn trong bài viết tiếp theo nhé.

Luôn cố gắng tìm kiếm 1 giải pháp tốt hơn

Sau một khoảng thời gian sử dụng, chúng mình thấy chi phí cho Crowdin là khá lớn nên đã tìm hiểu các công cụ khác trên thị trường. Một trong những ứng cử viên sáng giá nhất là Phrase với khả năng quản lý content không hề thua kém, việc hỗ trợ dịch thuật cũng khá tốt. Cả hai bên đều hỗ trợ nhiều nền tảng cùng định dạng file khá đa dạng như XML, YML, JSON, XLSX, CSV,…

Điểm khác biệt lớn nhất có lẽ là Crowdin phù hợp với những phòng ban ít người, còn Phrase hỗ trợ tốt hơn cho các bộ phận đông người nhờ tính năng tạo và quản lý job cho các thành viên trong team:

Ngoài ra khi dùng tính năng hỗ trợ dịch thuật của Phrase, đôi lúc bạn sẽ thấy những hướng dẫn tưởng chừng rất nhỏ nhặt nhưng lại vô cùng hữu ích, ví dụ như quy định số nhiều chẳng hạn:

Không chỉ vậy, Phrase có rất nhiều hướng dẫn như thế này, bạn sẽ tiết kiệm kha khá thời gian đi tìm hiểu đó:

Tính toán chi phí bỏ ra thì Phrase sẽ giảm đi đôi chút, tuy nhiên tại thời điểm đó đội UXW có rất ít người, hệ thống code đã tích hợp đầy đủ để sử dụng Crowdin, đồng thời nhiều tính năng của Phrase khá thừa nên chúng mình “ngựa quen đường cũ”: dùng Crowdin thôi 🤣

Đến cuối năm 2020, chúng mình quyết định tìm hiểu và học cách dùng Git sau khi tìm hiểu và tham khảo ý tưởng từ các thành viên trong công ty.

Về cơ bản, Git là một hệ thống giúp quản lý nội dung theo từng phiên bản riêng biệt với nhiều ưu điểm: dễ học, dễ dùng và miễn phí. Nói là vậy, nhưng khi mới tiếp xúc với Git, đội UXW cũng phải thử nghiệm và tập khá nhiều. Đội dev tạo riêng một kho lưu trữ “phake” — các UXW tha hồ mà nghịch mấy câu lệnh sau đến khi nào thành thạo thì thôi:

  • git checkout: dùng để mở hoặc chuyển đổi giữa các nhánh làm việc
  • git add: thay đổi gì đó trong nhánh bạn đang làm
  • git commit: lưu lại những gì bạn đã thay đổi
  • git push: đẩy các thay đổi này lên repo
  • (còn vài cái nữa mà mình quên rồi, các bạn thông cảm…)

Rất tiếc là các thành viên trong đội UXW low tech cực kỳ: nếu không gõ nhầm sang lệnh khác thì cũng là sai thứ tự, hoặc thậm chí là đẩy nhầm sang nhánh khác… Sau một thời gian cố gắng, mình đã học vẹt bằng cách chụp ảnh lại các bước cần làm như này:

Các bạn biết rồi đấy, ưu điểm của học vẹt là giải quyết vấn đề cực nhanh. Chúng mình làm xong các bài tập thực hành chỉ trong vài nốt nhạc. Không chỉ vậy, hàng loạt các task cũng đã được thử nghiệm thành công và chúng mình chỉ chờ đến ngày thực chiến.

Nhưng chuyện gì cũng có hai mặt của nó: chỉ cần gặp phải thay đổi nhỏ là chúng mình chịu thua, thậm chí gõ nhầm và không thể xử lý được các lỗi kỹ thuật. Khá nhiều lần đội UXW đã phải mang máy sang ngồi chầu chực cạnh các dev để nhờ họ giải quyết hậu quả. Chưa kể, mục đích cơ bản khi dùng Git là quản lý content theo từng phiên bản không còn được ưu tiên nữa, nên chúng mình đã quyết định dừng lại sau khoảng nửa năm dùng Git.

Ông cha ta có câu “tự lực cánh sinh”, có nghĩa là tự giải quyết khó khăn và không trông chờ vào người khác. Thật vậy, nếu VinID có thể tự làm một công cụ nội bộ thì công cụ đó chắc chắn sẽ giải quyết được các vấn đề chúng mình đang gặp phải. Chưa kể, công cụ đó vừa bảo mật, vừa có thể cập nhật để phù hợp với tình hình thực tế. Chúng mình đã mơ về một ngày mà đội UXW có thể tiết kiệm được rất nhiều thời gian cho cả việc viết nội dung lẫn làm key Crowdin, từ đó tập trung vào việc nghiên cứu và nâng cao tay nghề.

Chúng mình đã nghiên cứu các plugin và công cụ tương tự ở thị trường để có một cái nhìn tổng quan nhất, từ đó tổng hợp lại những tính năng thiết yếu và chuẩn bị thật kĩ càng để gửi sang đội dev. Các bạn cũng có thể tham khảo những plugin này trên Figma — chúng rất hữu dụng đó.

Tuy nhiên sau một thời gian chuẩn bị và bàn bạc cùng đội kỹ sư, chúng mình thấy nhược điểm rất lớn của cách này là cực kỳ tốn nhân lực và thời gian, trong khi số lượng người sử dụng thì lại khá ít ỏi. Vậy nên tại thời điểm này, chúng mình sẽ tạm gác lại dự án xây dựng công cụ nội bộ và tiếp tục trung thành với các phần mềm hiện có.

Đến đây là hết rồi

Trong những năm vừa qua, chúng mình luôn tìm cách cải thiện để tạo ra một hệ thống quản lý nội dung chỉn chu, gọn gàng và dễ dùng nhất có thể. Dù còn nhiều thiếu sót, nhưng hy vọng những chia sẻ của trên của chúng mình sẽ mang lại cho bạn thêm 1 gợi ý mới mẻ về việc quản lý nội dung. Còn bạn thì sao? Hãy cùng nhau chia sẻ cách mà bạn đang áp dụng để quản lý content cho chúng mình biết với nhé!

Hẹn gặp lại các bạn trong bài viết tiếp theo về kinh nghiệm dùng công cụ quản lý nội dung của bọn mình hiện tại: Crowdin. Cùng đón chờ nha ❤️

P.S. Những bức ảnh trong bài viết được thực hiện bởi artist Ry Nguyen, các bạn có thể xem thêm các tác phẩm khác của Ry tại đây nha:

Instagram: https://www.instagram.com/savana.vn/

Dribbble: https://dribbble.com/rynguyen

Còn đây là LinkedIn của hai thành viên trong team, rất mong được các bạn theo dõi và connect ❤️

--

--

Minh Nguyen
One Mount Product Design

I’m currently a UX Writer at One Mount, taking care of the content across the entire VinID app.