Tối ưu SEO website CSR (React, Angular) bằng kĩ thuật PreCrawl

Gần đây, mình có phải gặp một bài toán khá hay, với nhu cầu là thiết kế một blog với 3 tiêu chí

  • Quản Lý Nội Dung Động: Các bài viết, tag, category cần được động, có thể quản lý (thêm sửa xoá mới) hoàn toàn trên giao diện để cho những người không rành về công nghệ cũng có thể vận hành được
  • Miễn phí: Quan trọng nhất, không được mất phí cho bất kì phần nào của hệ thống, đây là yêu cầu quan trọng nhất, vì cái này sẽ phục vụ cho 1 số tổ chức có kinh phí eo hẹp, hoặc cho cá nhân viết blog theo sở thích, … và không mong muốn chi thêm 1 khoản phí cho website (tất nhiên là không tính tới domain)
  • SEO: Website phải tốt cho SEO

Disclaimer: Đây không phải là một bài toán của blog mình, hiện tại blog của mình đang sử dụng WordPress, và nó tốn chi phí hàng tháng, nhưng cũng đáp ứng đủ các nhu cầu của mình.

Nếu cần Solution tối ưu nhất, hãy đi đến hướng đi cuối

Hướng đi 1: Static Site Generator (SSG)

Hướng tiếp cận đầu tiên của mình là sử dụng 1 opensource sinh ra các trang tĩnh cho blog, sau đó deploy bản được build ra lên một số trang cho host trang tĩnh miễn phí như Firebase Hosting, Github Page, …

Giải pháp này thì đã có rất nhiều open source, bạn có thể tham khảo tại đây, dưới mục Blog: https://github.com/myles/awesome-static-generators#blogs

Nhìn chung luồng này sẽ dạng như sau

  • Người dùng sẽ viết bài ở dạng Markdown, hoặc có thể là viết ở Notion, …
  • Sẽ cần 1 cái gì đó trigger thực hiện build khi viết bài xong, có thể là ci/cd tự động khi push markdown ở github, hoặc ở notion có lắng nghe sự kiện
  • Lúc này hệ thống sẽ build ra bản trang tĩnh, và có thể được deploy lên các trang hosting cho phép deploy trang tĩnh
image - quochung.cyou PTIT
image 1 - quochung.cyou PTIT
  • Ví dụ: Hexo – Viết các file markdown, khi chạy generate sẽ sinh folder build

Pros

  • Miễn phí
  • SEO tốt
  • Có thể viết động, người dùng vận hành vào viết bài được nếu mà CI-CD đã làm hết -> Tuy nhiên vẫn chưa ở mức cao nhất là có trang quản lý riêng như mong muốn ban đầu lắm

Cons:

  • Đa số các giải pháp đều cần build lại ra trang tĩnh mỗi lần sửa đổi, và khi số lượng bài viết tăng lên thì càng tốn thời gian hơn.
  • Khi cần sửa đổi bài viết, thêm bài viết đều cần build lại, chưa thể vào xem thử tức thì
  • Chưa có giao diện quản lý trực quan

Hướng đi 2: NextJS

Một hướng đi thứ 2 để tối ưu SEO là sử dụng 1 framework server side rendering, có khá nhiều framework như vậy. Điển hình là NextJS.

Ta có thể sử dụng 1 database miễn phí, query bằng api để hỗ trợ trang web động.

Tuy nhiên NextJS nếu muốn build ra các dạng trang tĩnh, để có thể deploy free trên các trang host tĩnh như Github Page, Firebase Hosting, …. thì bắt buộc sẽ cần render toàn bộ trước.

Cụ thể sẽ cần sử dụng  getStaticPaths, và lúc thời điểm build ra bản output, thì sẽ cần query toàn bộ bài viết ở database, và build.

image 2 - quochung.cyou PTIT

Pros

  • Miễn phí
  • SEO tốt
  • Có thể viết động, chỉnh sửa động bằng giao diện do có thể code call api vào database động

Cons:

  • Thời gian build cực kì lâu, vì đa số các hosting free static site sẽ xoá toàn bộ file mỗi lần upload lên, và mỗi lần build thì cần build toàn bộ.

Hướng đi 3 – Solution: Pre-Crawl

Ở cách làm này, ta sẽ sử dụng CSR truyền thống để khi người dùng lướt web, sẽ đọc bài viết, dữ liệu được load động từ API. Và việc tạo bài viết, chuyên mục, … được admin vận hành tạo từ trang quản trị, cũng sẽ thực hiện qua API Database, ở đây sử dụng API Supabase

Mấu chốt là ví dụ như nếu sử dụng React, thì SEO sẽ rất kém, vì React đi theo dạng sử dụng đa số là JS và để JS build ra HTML. Nên các bot crawl của Google, Bing, … khi vào trang web nếu không chạy được js sẽ không load ra dữ liệu gì cả

Ví dụ hình ảnh một trang web sử dụng CSR sẽ trông như nào với Bot qua http://botsimulator.com/:

  • Kết quả nhận được, bot không lấy được dữ liệu gì cả, chỉ có tên trang web, keyword, desc, … đều rỗng
image 3 - quochung.cyou PTIT
image 5 - quochung.cyou PTIT

Phương án đề ra là ta sẽ sử dụng một luồng nghiệp vụ khác, riêng biệt, chuyên thực hiện việc đi vào các trang web như người dùng mở browser vào web vậy, sau đó cache lại các dữ liệu html vào 1 trang lưu tĩnh, lúc này khi Bot tới, ta sẽ có 1 tầng proxy kiểm tra xem có phải là Bot không, và redirect Bot sang trang tĩnh html đã được xử lý xong, còn người dùng thì đi luồng thông thường.

Có thể nhìn biểu đồ sau với các công nghệ sử dụng:

  • Proxy bên trên xử lý redirect: Cloudflare Worker Route + Cloudflare Worker
  • Lưu trữ HTML: Supabase Storage
  • Trang tĩnh: lưu trữ tại Cloudflare Page, dev bằng React
  • Thực hiện crawl trang web: Github Action
  • Database + API động bài viết: Supabase Database
image 7 - quochung.cyou PTIT

Kết quả nhận được:

  • Bot sẽ crawl được các dữ liệu trong bài viết (Trong ảnh ở phần Indexable Page Text)
image 4 - quochung.cyou PTIT
image 6 - quochung.cyou PTIT

Pros

  • Miễn phí
  • SEO tốt
  • Có thể viết động, chỉnh sửa động bằng giao diện do có thể code call api vào database động
  • Build nhanh, do trang build ra là trang csr chỉ chứa code call api cho user <- Xử lý được hướng đi 1,2

Cons:

  • Sẽ cần flow crawl dữ liệu, cái này thì có thể chạy bằng manual cũng được, mình sử dụng 1 workflow trên Github Action để crawl, Github Action sẽ free 2200 phút / tháng (khoảng chạy được 1 tiếng /ngày, vì vậy sẽ cần triển khai logic dạng kiểm tra có nên crawl lại 1 trang không bằng thời gian cập nhật, … tuỳ vào nghiệp vụ)

Code triển khai + chi tiết setup với techstack bên trên

https://github.com/quochung-cyou/csr-seo-page-crawl

[Web-Buổi 3] Tìm hiểu về Responsive

Mục lục

  • Grid
  • FlexBox
  • Media Query
  • Break point
  • Viewport
  • GridView
  • Flexible Media
  • CSS Sass

I. Grid

  • Grid là một hệ thống layout mạnh mẽ, cho phép bạn tạo ra các layout phức tạp và đẹp mắt mà không cần phải sử dụng các thẻ div lồng nhau.
  • Grid được chia thành 2 phần chính là Grid Container và Grid Item.
  • Grid Container là phần bao bọc các Grid Item.
  • Grid Item là các phần tử con của Grid Container.

Example Code in MD:

    <div class="grid-container">
        <div class="grid-item">1</div>
        <div class="grid-item">2</div>
        <div class="grid-item">3</div>
        <div class="grid-item">4</div>
        <div class="grid-item">5</div>
        <div class="grid-item">6</div>
        <div class="grid-item">7</div>
        <div class="grid-item">8</div>
        <div class="grid-item">9</div>
    </div>
Grid

Display Grid:

    .grid-container {
        display: grid;
    }

Grid Template Columns:

    .grid-container {
        display: grid;
        grid-template-columns: 100px 100px 100px;
    }

Grid Template Rows:

    .grid-container {
        display: grid;
        grid-template-columns: 100px 100px 100px;
        grid-template-rows: 100px 100px 100px;
    }

Grid Gap:

    .grid-container {
        display: grid;
        grid-template-columns: 100px 100px 100px;
        grid-template-rows: 100px 100px 100px;
        grid-gap: 10px;
    }

Grid tự động cân bằng

    .grid-container {
        display: grid;
        grid-template-columns: auto auto auto;
        grid-template-rows: auto auto auto;
        grid-gap: 10px;
    }
Grid

Grid cân bằng theo tỉ lệ

    .grid-container {
        display: grid;
        grid-template-columns: 20% 30% 50%
        grid-gap: 10px;
    }
Grid

Tuỳ chỉnh vùng theo thuộc tính

    .item8 {
    grid-area: 1 / 2 / 5 / 6;
    }
Grid
Grid

II. FlexBox

  • FlexBox là một hệ thống layout mạnh mẽ, cho phép bạn tạo ra các layout phức tạp và đẹp mắt mà không cần phải sử dụng các thẻ div lồng nhau.
  • FlexBox được chia thành 2 phần chính là Flex Container và Flex Item.
  • Flex Container là phần bao bọc các Flex Item.
  • Flex Item là các phần tử con của Flex Container.
FlexBox

Example Code in MD:

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>
FlexBox

III. Media Query

  • Media Query là một công cụ cho phép bạn thay đổi style của một trang web dựa trên các điều kiện nhất định.
  • Media Query được sử dụng để tạo ra các trang web đáp ứng (responsive web).
  • Media Query được sử dụng để tạo ra các trang web có thể hiển thị đẹp trên các thiết bị khác nhau, với các kích thước màn hình khác nhau.

Example Code in MD:

@media only screen and (max-width: 600px) {
  body {
    background-color: lightblue;
  }
}
Media Query

IV. Break point

  • Breakpoint, là những điểm (chiều rộng màn hình của thiết bị) mà ở đó giao diện được chuyển đổi cho phù hợp với thiết bị hiện tại, ví dụ như màn hình rộng hơn 1024px, thì có background-color màu đỏ, nhỏ hơn 1024px thì background-color màu xanh, khi này ta gọi 1024 là breakpoint.
  • Tùy vào chiều rộng hiển thị của thiết bị mà breakpoint sẽ khác nhau, hiện nay có rất nhiều thiết bị, tương ứng sẽ có nhiều chiều rộng khác nhau, nên sẽ có nhiều breakpoint khác nhau, do đó ta không thể thiết lập beakpoint cho từng loại thiết bị được.

Điểm breakpoint

  • 320 px Màn hình chiều dọc cho smartphone nhỏ (VD iPhone 5)
  • 480 px Màn hình chiều ngang cho smartphone nhỏ
  • 640 px Màn hình chiều ngang cho smartphone vừa
  • 768 px Màn hình chiều dọc cho tablet (VD: iPad)
  • 1024 px Màn hình chiều ngang cho tablet (VD: iPad), hoặc chiều dọc cho tablet lớn (VD iPad Pro)
@media only screen and (min-width: 320px) {
 body{
   background-color: orange;
  }
}
Break point

V. Viewport

  • Viewport là khu vực hiển thị nội dung trên trình duyệt.
  • Viewport thay đổi theo thiết bị, và sẽ nhỏ hơn trên điện thoại di động so với màn hình máy tính.
  • Trước khi có máy tính bảng và điện thoại di động, các trang web được thiết kế chỉ cho màn hình máy tính, và việc thiết kế tĩnh và kích thước cố định là phổ biến.
  • Sau đó, khi chúng ta bắt đầu lướt web bằng máy tính bảng và điện thoại di động, các trang web có kích thước cố định quá lớn để vừa với viewport. Để khắc phục điều này, các trình duyệt trên các thiết bị đó thu nhỏ toàn bộ trang web để vừa với màn hình.
  • Khác biệt giữa có viewport và không có viewport:
  • Một trang web không có thẻ meta viewport sẽ được hiển thị với độ rộng của trang web, không phụ thuộc vào thiết bị.
  • Một trang web với thẻ meta viewport sẽ được hiển thị với độ rộng của thiết bị, và với tỷ lệ khung hình cố định.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
  • width=device-width phù hợp với chiều rộng của thiết bị (đừng quên để thẻ meta viewport trong thẻ <head>)
  • initial-scale=1.0 thiết lập tỷ lệ khung hình của trang web
  • user-scalable=no ngăn người dùng phóng to hoặc thu nhỏ trang web
  • minimum-scale=1.0 ngăn người dùng thu nhỏ trang web
  • maximum-scale=1.0 ngăn người dùng phóng to trang web

VI. GridView

!!!

VII. Flexible Media

Flexible Media
img {
  max-width: 100%;

  /* just in case, to force correct aspect ratio */
  height: auto !important;
}

VIII. CSS Sass

  • Sass là một ngôn ngữ mở rộng của CSS, nó có thể giúp việc viết CSS trở nên dễ dàng và nhanh hơn.
  • Sass là chữ viết tắt của Syntactically Awesome Style Sheets, chương trình tiền xử lý bằng ngôn ngữ kịch bản (Preprocessor Scripting Language ), sẽ được biên dịch thành CSS. Nghĩa là, mình sẽ làm style bằng SASS, rồi SASS sẽ render việc mình làm thành file CSS.
  • Sass có 2 phiên bản là Sass và SCSS, 2 phiên bản này khác nhau ở cú pháp, nhưng cùng có chức năng tương tự nhau.

[Android] P-Connect Social

https://github.com/quochung-cyou/P-Connect

Author

  • quochungcyou

Description

  • P-Connect is an Android app written in Java, developed by quochungcyou, made during ProGApp competition in one month. It provides a comprehensive experience with its user-friendly UI/UX, smooth animations, and top performance. With fast loading times and an elegant design, P-Connect offers a plethora of features such as the latest headlines, chat functions, and even a small dating app. Additionally, the code is clean and organized with an MVC structure to ensure maximum efficiency.

Prerequisites

  • To run this software, you need an editor with java support, java – version 11 or higher,android-studio
  • Install java 11 using the commands: sudo apt update sudo apt install openjdk-11-jre-headless
  • Install android-studio sudo snap install android-studio --classic

Setup

  • Clone the project
  • Open in android-studio

Technologies Used

  • Java (version 11)
  • Android
  • Gradle (7.1)

Demo image

1 - quochung.cyou PTIT
2 - quochung.cyou PTIT
3 - quochung.cyou PTIT
4 - quochung.cyou PTIT
5 - quochung.cyou PTIT
6 - quochung.cyou PTIT
7 - quochung.cyou PTIT

License Information

  • This software is licensed under MIT License.
  • Read More on the license.
MIT License

Copyright (c) 2023 QuocHung

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.