Dang  Tu

Dang Tu

1658497701

Cách Tạo Bản Tin Với Twitter Revue, Next.js & Tailwindcss

Tìm hiểu cách tạo bản tin với các API Revue, các tuyến API Next.js và Tailwindcss. Cách tốt nhất để đưa Bản tin vào ứng dụng / trang web Next.js của bạn.

Bạn có một bản tin email hay đang cân nhắc việc bắt đầu một bản tin? Bản tin email cung cấp cho người đăng ký của bạn thông tin cập nhật thường xuyên về công việc, sản phẩm, đam mê, cuộc sống, hành trình của bạn, bất cứ điều gì bạn thấy phù hợp để chia sẻ. Chúng tôi có một số nhà cung cấp / sản phẩm / trang web tuyệt vời giúp chúng tôi bắt đầu ngay với dịch vụ bản tin email. Buttondown, Mailchimp, MailerLite, Substack chỉ là một vài cái tên ở đây.

Đầu năm nay, Twitter thông báo mua lại Revue , một dịch vụ giúp mọi người bắt đầu và xuất bản các bản tin biên tập miễn phí và dễ dàng. Không chỉ vậy. Twitter cũng đã cung cấp các tính năng Pro của Revue miễn phí cho tất cả các tài khoản.

Vài ngày trước, một tweet từ tài khoản chính thức của Revue xác nhận rằng họ sẽ cho phép mọi người đăng ký nhận bản tin Revue của bạn trực tiếp từ hồ sơ Twitter của bạn. Giữ một số cuộc tranh luận sang một bên, tôi nghĩ đó là một động thái tuyệt vời.

Là chủ sở hữu của một bản tin, chúng tôi có thể quảng bá nó theo nhiều cách.

  • Chúng tôi có thể liên kết đến trang bản tin từ trang web, blog của chúng tôi.
  • Chúng tôi có thể nhúng biểu mẫu đăng ký vào trang web của mình bằng cách sử dụng các đoạn mã JavaScript, HTML, CSS đơn giản do nhà cung cấp cung cấp.
  • Cuối cùng, nếu nhà cung cấp bản tin cung cấp API để truy cập dữ liệu, chúng tôi có thể tạo, quản lý bản tin hoàn toàn trong tầm kiểm soát của chúng tôi. Đây là một cách sử dụng mạnh mẽ mang lại cho người dùng của bạn cảm giác onenesslà một phần của cùng một trang web, giao diện tương tự.

Vậy, kế hoạch là gì?

Hướng dẫn này sẽ dạy cách sử dụng các RevueAPI để tìm nạp dữ liệu vào một Next.jsứng dụng bằng cách sử dụng các tuyến API (các chức năng không có máy chủ). Chúng tôi cũng sẽ sử dụng tailwindcssđể cung cấp cho ứng dụng một giao diện đẹp hơn.

Tôi đang trên đường chuyển trang web cũ của mình sang trang web mới bằng cách sử dụng Next.jstailwindcss, và bản tin sẽ là một phần của nó. Vì vậy, đây là một cơ hội tuyệt vời để chia sẻ những gì tôi đã thực hiện và học được.

TL; DR

Nếu bạn muốn chuyển sang ứng dụng cuối cùng hoặc mã nguồn sớm, đây là các liên kết,

Thiết lập Dịch vụ Bản tin bằng Revue

Để thiết lập bản tin với Revue, hãy đăng ký https://www.getrevue.co/ bằng tài khoản Twitter hoặc email của bạn.

Revue Đăng ký

Tiếp theo, đăng nhập vào tài khoản của bạn để thiết lập bản tin bằng cách cung cấp tên, mô tả, bố cục, vấn đề và lịch trình. Bạn có thể tích hợp nhiều dịch vụ như Twitter, Facebook, Instagram với tài khoản Revue của mình để lấy nội dung từ chúng để thêm vào bản tin. Ngoài ra, bạn có thể tìm nạp dữ liệu bằng nguồn cấp dữ liệu RSS. Bạn cũng có thể tích hợp nguồn cấp dữ liệu RSS của blog được hỗ trợ bởi Hshnode của mình. Tôi đã thực hiện điều ước của mình với Sam Sycamore rồi 😆!

Phần cuối của trang tích hợp hiển thị khóa API của bạn để truy cập dữ liệu bản tin qua các yêu cầu HTTP. Vui lòng sao chép chìa khóa này và giữ nó an toàn.

Mã API

Khóa API này sẽ là một phần của Authorizationgiá trị tiêu đề khi sử dụng các API Revue. Đây là liên kết để tìm hiểu về tất cả các API có sẵn công khai. Trong hướng dẫn này, chúng tôi sẽ sử dụng những thứ sau,

  • POST /v2/subscribers: Thêm người đăng ký vào danh sách.
  • GET /v2/subscribers: Trả về danh sách những người đăng ký đang hoạt động của bạn.
  • GET /v2/issues: Trả về danh sách các vấn đề đã gửi của bạn.

Tuy nhiên, trước đó, chúng ta hãy xây dựng giao diện người dùng của ứng dụng Đăng ký Bản tin.

Tạo ứng dụng đăng ký nhận bản tin bằng Next.js và Tailwindcss

Có rất nhiều dự án dành cho người mới bắt đầu có sẵn trong GitHub để bắt đầu với Next.js và Tailwindcss. Yêu thích cá nhân của tôi là next-starter-tailwind vì tính đơn giản của nó. Tôi sẽ sử dụng nó làm mẫu để tạo kho lưu trữ cho ứng dụng đăng ký bản tin. Vui lòng sử dụng bất kỳ dự án khởi đầu nào khác mà bạn cảm thấy thoải mái.

Vui lòng tạo một kho lưu trữ bằng cách nhấp vào Use this templatenút của next-starter-tailwindkho lưu trữ.

image.png

Cung cấp thông tin chi tiết được yêu cầu và tạo kho lưu trữ từ mẫu.

image.png

Bây giờ sao chép kho lưu trữ và duyệt đến thư mục dự án. Mở dấu nhắc lệnh hoặc cửa sổ đầu cuối để cài đặt phần phụ thuộc bằng lệnh sau,

npm install # Or, yarn install

Ở giai đoạn này, vui lòng mở dự án bằng trình soạn thảo mã yêu thích của bạn (Mã VS, trong trường hợp của tôi) và thực hiện các thay đổi mã nhỏ. Mở header.jstệp trong componentsthư mục và tìm Next.js Starter Tailwindvăn bản. Thay đổi văn bản này thành Newsletter demo powered by Next.js Revue Tailwind. Ngoài ra, bạn có thể thay đổi tên người tạo, thông tin GitHub trong footer.jstệp.

Bây giờ, hãy lưu các thay đổi của bạn và sử dụng lệnh này từ dấu nhắc lệnh của bạn để khởi chạy ứng dụng.

npm run dev # Or, yarn dev

Truy cập ứng dụng bằng URL http://localhost:3000. Bạn sẽ thấy giao diện người dùng ban đầu xuất hiện.

Giao diện người dùng ban đầu

Tạo biểu mẫu đăng ký

Hãy tạo một biểu mẫu đăng ký cơ bản với một trường email và một nút để đăng ký. Vui lòng tạo một tệp mới có tên Subscribe.jstrong componentsthư mục với nội dung sau.

const Subscribe = () => {
  return (
    <div className="border border-gray-200 rounded p-6 my-4 w-full bg-gray-50">
      <p className="text-gray-900 mb-6 text-lg md:text-xl">
         Want to keep your brain engaged with great UI/UX learning content?
      </p>
      <p className="text-gray-800 dark:text-gray-400 mb-10 text-base">
        Enter your email address and you'll be be added to my email newsletter, of which you can opt out any time.
      </p>
      <form className="relative my-4">
        <input
          aria-label="Email for newsletter"
          placeholder="john@email.com"
          type="email"
          autoComplete="email"
          required
          className="py-4 px-0 text-md bg-transparent w-9/12 text-gray-900 border-b-2 border-gray-600 dark:border-gray-400 dark:text-white focus:border-brand focus-visible:outline-none"
        />
        <button
          className="flex justify-center px-5 py-4 mt-8 bg-green-600 text-white font-bold text-lg"
          type="submit"
        >
          Subscribe
        </button>
      </form>

      <p className="text-xl text-gray-800 dark:text-gray-200">
        14 subscribers . 3 issues
      </p>
    </div>
  );
};

export default Subscribe;

Nó là một thành phần phản ứng với một biểu mẫu đơn giản có một trường email và một nút. Chúng tôi cũng đã mã hóa số người đăng ký và số vấn đề. Sau đó, chúng tôi sẽ thực hiện các lệnh gọi API để tìm nạp chúng. Chúng tôi đã tạo kiểu cho phần tử HTML bằng cách sử dụng các lớp tailwindcss .

Bây giờ chuyển sang thư mục index.jsbên dưới pages. Thay thế nội dung của tệp bằng nội dung sau,

import Subscribe from "@components/Subscribe";

export default function IndexPage() {
  return (
    <Subscribe />
  );
}

Ở đây, chúng tôi đang nhập và sử dụng Subscribethành phần để khi tải ứng dụng, nó sẽ hiển thị biểu mẫu đăng ký bản tin. Hãy làm mới trang. Bạn sẽ thấy các biểu mẫu đăng ký như,

Mẫu đăng ký

Tạo các tuyến API Next.js để đăng ký và nhiều hơn nữa

Bây giờ đã đến lúc tạo Next.js API Routesđể đăng ký một người đăng ký mới, lấy số lượng người đăng ký và danh sách các vấn đề.

Các chức năng không máy chủ Next.js

Với các Định tuyến API của Next.js , bạn có thể dễ dàng tạo các điểm cuối API. Ở chế độ nền, nó sử dụng các chức năng không máy chủ của Node.js. Bạn cần tạo các chức năng này bên trong pages/apithư mục. Vì vậy, trước tiên chúng ta hãy tạo một thư mục được gọi là apidưới pagesthư mục.

Chúng tôi sẽ cần khóa API Revue ngay bây giờ. Vui lòng tạo .env.localtệp ở thư mục gốc của thư mục dự án với dòng sau,

REVUE_API_KEY=<REPLACE_THIS_WITH_REVUE_API_KEY>

Vui lòng sử dụng của API Keybạn mà bạn đã sao chép từ trang tích hợp thu hồi trước đó.

Ở giai đoạn này, bạn cần khởi động lại máy chủ cục bộ để biến môi trường được tải trong ứng dụng của chúng tôi. Vì vậy, hãy dừng máy chủ và khởi động lại nó bằng yarn devlệnh.

Hãy tạo tuyến API để đăng ký một người đăng ký mới.

Nhưng, cố lên! Tại sao chúng tôi không thể sử dụng API Revue trực tiếp?

Bạn có thể. Có thể sử dụng các API Revue trực tiếp trong các thành phần React của bạn. Tuy nhiên, có một số lợi thế khi sử dụng nó thông qua các API Next.js.

  • Trong tương lai, nếu bạn muốn sử dụng một dịch vụ bản tin khác ngoài Revue, mã thành phần giao diện người dùng của bạn không bao giờ thay đổi. Bạn chỉ cần thay đổi chức năng serverless và triển khai lại.
  • Có một sự trừu tượng. Nó giúp bạn triển khai và lưu trữ riêng API cùng với các trường hợp sử dụng kinh doanh của riêng bạn.
  • Việc truy cập trực tiếp các API này ở phía máy khách sẽ khiến bạn gặp rủi ro về rủi ro API keymà bất kỳ ai cũng có thể lấy được dễ dàng bằng cách kiểm tra các yêu cầu mạng. Bạn không muốn điều đó!

Được rồi, hãy tiếp tục.

Tạo tuyến API Next.js để đăng ký một người đăng ký mới

Tạo một tệp được gọi là thư mục subscribe.jsbên trong pages/api. Điều đó có nghĩa là lộ trình API của chúng tôi sẽ có thể truy cập được từ các thành phần giao diện người dùng bằng cách sử dụng URI /api/subscribe. Vui lòng dán nội dung sau vào subscribe.jstệp.

export default async function handler(req, res) {
    // 1. Get the email from the payload and
    // validate if it is empty.
    const { email } = req.body;
    if (!email) {
        return res.status(400).json({error: 'Please provide an email id.'});
    }

    // 2. Use the Revue API Key and create a subscriber using
    // the email we pass to the API. Please note, we pass the
    // API Key in the 'Authorization' header.
    try {
        const API_KEY = process.env.REVUE_API_KEY;
        const response = await fetch(
            `https://www.getrevue.co/api/v2/subscribers`,
            {
                method: 'POST',
                body: JSON.stringify({email: email, double_opt_in: false}),
                headers: {
                    'Authorization': `Token ${API_KEY}`,
                    'Content-Type': 'application/json'
                }
            }
        )

    // 3. We check in the response if the status is 400
    // If so, consider it as error and return. Otherwise a 201
    // for create        
        if (response.status >=400) {
            const message = await response.json();
            console.log(message.error.email[0]);
            return res.status(400).json({error: message.error.email[0]});
        }
        // Send a JSON response
        res.status(201).json({
            message: `Hey, ${email}, Please check your email and verify it. Can't wait to get you boarded.`,
            error: ''
        });
    } catch (err) {
    // 4. If the control goes inside the catch block
    // let us consider it as a server error(500)  
        return res.status(500).json({error: err.message || error.toString()});
    }
}

Một vài điều đang diễn ra trong chức năng trên.

  1. Khi ai đó gọi hàm API này, chúng tôi mong đợi một phần email của tải trọng. Vì vậy, trước tiên, hãy lấy email từ tải trọng và xác thực nếu nó trống.
  2. Tiếp theo, sử dụng email và API_KEY để gọi API Revue để đăng ký người đăng ký. Lưu ý tải trọng ở đây. Chúng tôi đang chuyển giá trị email và double_opt_ingiá trị như false. Trên thực tế, bạn sẽ KHÔNG chuyển giá trị double_opt_in sai vì bạn muốn người đăng ký của mình xác minh email trước khi xác nhận. Chúng tôi đang làm điều đó chỉ vì lợi ích của bản demo.
  3. Sau đó, chúng tôi kiểm tra responsenếu trạng thái là 400. Nếu vậy, hãy coi đó là một lỗi và quay lại với một thông báo lỗi. Nếu không, 201 để tạo và trả về với thông báo thành công.
  4. Cuối cùng, Nếu điều khiển đi vào bên trong khối bắt, chúng ta hãy coi đó là lỗi máy chủ (500).

Cập nhật mã giao diện người dùng để đăng ký người đăng ký

Chúng tôi sẽ cập nhật Subscribethành phần để sử dụng /api/subscribeAPI. Mở Subscribe.jstệp trong componentsthư mục và thực hiện các thay đổi này.

Nhập useStatehook từ reactđể quản lý một vài trạng thái. Thêm dòng này ở đầu tệp.

import { useState } from 'react';

Tạo ba biến trạng thái để xử lý email từ đầu vào của người dùng và thông báo lỗi, thành công từ lệnh gọi API. Thêm ba dòng này vào đầu Subscribehàm dưới dạng,

const Subscribe = () => {
 const [email, setEmail] = useState('');
 const [error, setError] = useState('');
 const [success, setSuccess] = useState('');
   return (
     ..... 
     {/* Rest of the code as is */}
     ....
   )
}

Tiếp theo, xử lý hai sự kiện. Một là để nắm bắt đầu vào của người dùng trong trường email và thứ hai là xử lý để gửi.

...
...
<form className="relative my-4" onSubmit={subscribeMe}>
     <input
       onChange={changeEmail}

Bây giờ là lúc để xác định cả hai subscribeMechangeEmailcác phương thức.

const subscribeMe = async (event) => {
  event.preventDefault();

  const res = await fetch("/api/subscribe", {
     body: JSON.stringify({ email: email }),
     headers: { 'Content-Type': 'application/json' },
     method: "POST",
  });

 const { error, message } = await res.json();
  if (error) {
     setError(error);
  } else {
     setSuccess(message);
  }
};

const changeEmail = (event) => {
 const email = event.target.value;
 setEmail(email);
}

Trong subscribeMephương thức này, chúng tôi gọi là API /api/subscribe, chuyển giá trị email dưới dạng tải trọng. Sau đó, chúng tôi xử lý lỗi và thông báo thành công.

Cuối cùng, hãy hiển thị thành công và thông báo lỗi trong giao diện người dùng. Thêm mã này ngay sau phần tử biểu mẫu.

{success 
       ? 
    <span className="flex items-center text-sm font-bold text-green-700"> 
         {success}
    </span> 
       : 
    <span className="flex items-center text-sm font-bold text-red-800">
          {error} 
    </span>
}

Tuyệt vời, bây giờ hãy truy cập ứng dụng và cung cấp một id email để đăng ký. Vì chúng tôi đã tắt xác minh email, bạn có thể kiểm tra nó bằng một id email tùy ý. Vui lòng xem toàn bộ tệp nguồn từ đây .

Đăng ký thành công

Để xác minh, địa chỉ email đã được thêm thành công, vào trang người đăng ký trong tài khoản của bạn. Bạn sẽ thấy id email mới này được thêm vào,

Người đăng ký phụ đã được thêm

Hãy đảm bảo sử dụng xác minh email bằng cách bật double_opt_in: truehàm API để sử dụng sản xuất.

Hãy thử lại cùng một id email để cố gắng đăng ký!

đăng ký thất bại

Đúng, bạn sẽ gặp lỗi đó. Đó là tất cả. Đăng ký hoạt động tốt.

Nhận số lượng người đăng ký

Được rồi, hãy tính số người đăng ký. Vì vậy, bây giờ chúng ta sẽ viết một hàm không máy chủ để tìm nạp số lượng người đăng ký. Hãy tạo một tệp có tên subscribers.jsdưới pages/apithư mục với nội dung sau.

export default async function handler(_, res) {
  const API_KEY = process.env.REVUE_API_KEY;
  const response = await fetch('https://www.getrevue.co/api/v2/subscribers', {
    headers: {
      Authorization: `Token ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    method: 'GET'
  });

  const data = await response.json();
  const count = data.length;

  res.setHeader(
    'Cache-Control',
    'public, s-maxage=1200, stale-while-revalidate=600'
  );

  return res.status(200).json({ count });
}

Chúng tôi sử dụng API Revue để tìm nạp danh sách người đăng ký và sau đó trả lại số lượng dưới dạng phản hồi. Vì vậy, bây giờ chúng ta phải sử dụng /api/subscribersURI để tìm nạp số lượng. Hãy làm nó.

Cập nhật mã giao diện người dùng để tìm nạp số lượng người đăng ký

Chúng tôi cần tìm nạp số lượng người đăng ký khi Subscribethành phần tải. Ngoài ra, nếu có người đăng ký mới, chúng tôi cần hiển thị số lượng cập nhật trong giao diện người dùng. Next.jshỗ trợ hai loại pre-rendering,

  • Static Generation(SSG): Trong trường hợp này, mọi thứ đều được biên dịch trước, tạo sẵn và lưu vào bộ nhớ đệm. Bạn không thấy những thay đổi trong nội dung của mình cho đến khi có một bản dựng khác. Nó hoạt động tốt nhất khi bạn xử lý dữ liệu tĩnh như các bài báo trên blog.
  • Server-Side Rendering(SSR): Tại đây, dữ liệu cho một trang được tạo theo yêu cầu cho mỗi yêu cầu.

Chúng tôi muốn tạo tĩnh càng nhiều càng tốt nhưng có thể không tránh được việc hiển thị phía máy chủ trong một số trường hợp. Đối với ứng dụng của chúng tôi, chúng tôi sẽ sử dụng SWR. Như được mô tả ở đây ,

SWRcó nguồn gốc từ stale-while-revalidate, một chiến lược vô hiệu hóa bộ nhớ cache HTTP được phổ biến bởi HTTP RFC 5861. SWR là một chiến lược trước tiên trả lại dữ liệu từ bộ nhớ cache (cũ), sau đó gửi yêu cầu tìm nạp (xác thực lại) và cuối cùng là dữ liệu cập nhật.

Với sự hỗ trợ của Next.js pre-renderingSWR, bạn có thể kết xuất trước trang cho SEO và cho phép lưu vào bộ nhớ đệm, xác thực lại và tìm nạp lại ở các khoảng thời gian ở phía máy khách.

Cài đặt swrthư viện bằng lệnh,

npm install swr #Or, yarn add swr

Thư swrviện cung cấp cho chúng ta một hook được gọi là useSWR. Nó có hai tham số, a keyvà một hàm tìm nạp. Giá keytrị là một chuỗi, thường là URL API mà chúng ta sẽ chuyển cho fetcherhàm và fetcherhàm có thể là một hàm không đồng bộ. Vì vậy, chúng ta hãy tạo một hàm tìm nạp đơn giản.

Vui lòng tạo một utilsthư mục ở thư mục gốc của dự án và tạo một fetcher.jstệp có nội dung sau,

export default async function Fetcher(...args) {
 const res = await fetch(...args);

 return res.json();
}

Tiếp theo, trong components/Subscribe.jstệp, hãy bao gồm hai lần nhập này.

import useSWR from 'swr';
import fetcher from '../utils/fetcher';

Bây giờ chúng ta có thể sử dụng useSWRhook để chuyển API ( api/subscribers) và hàm tìm nạp.

const Subscribe = () => {

  const [email, setEmail] = useState('');
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  // --- above is old code ---

  const { data } = useSWR('/api/subscribers', fetcher);
  const subscriberCount = data?.count;

Xin lưu ý, chúng tôi sử dụng JavaScript optional chaining(?.)tính năng để lấy giá trị đếm. Nó xử lý undefinedgiá trị một cách an toàn.

Mỗi khi dữ liệu được thay đổi ở phần cuối, subscriberCountbiến sẽ có số lượng mới nhất.

Cuối cùng là sử dụng subscriberCountbiến trạng thái thay vì giá trị được mã hóa cứng.

<p className="text-sm text-gray-800 dark:text-gray-200">
  { subscriberCount } subscribers . 3 issues
</p>

Đó là tất cả. Làm mới ứng dụng và xem phản ánh số lượng thực tế.

Số lượng người đăng ký

Nhận danh sách vấn đề

Bây giờ chúng ta cần lấy danh sách vấn đề và số lượng các vấn đề đã xuất bản. Vì vậy, chúng ta phải viết lại một hàm serverless để tìm nạp các chi tiết này. Nhưng chờ đã, tôi sẽ không làm điều đó trong hướng dẫn này. Hãy xem nó như một bài tập để thử sức.

Gợi ý: Bạn cần sử dụng API Revue này để tìm nạp dữ liệu => GET /v2/issues. Nếu bạn cần trợ giúp, mã API có ở đây và các thay đổi thành phần ở đây để tham khảo.

Cuối cùng, giao diện người dùng phải có số lượng vấn đề thực tế và danh sách các vấn đề đã xuất bản như thế này (tôi có một vấn đề thử nghiệm).

trang cuối cùng

Hãy triển khai

Xin chúc mừng!!! Ứng dụng đã sẵn sàng để sử dụng. Nhưng, nó chỉ có sẵn với bạn. Hãy triển khai nó một cách công khai. Chúng tôi sẽ sử dụng nền tảng Vercel để triển khai ứng dụng của mình. Việc triển khai ứng dụng Next.js trên Vercel rất dễ dàng bằng một vài bước đơn giản. Để điều đó xảy ra, vui lòng cam kết và đẩy tất cả các thay đổi mã của bạn vào GitHubkho lưu trữ.

Tạo tài khoản với Vercel, đăng nhập và nhấp vào New Projectnút để bắt đầu.

image.png

Tiếp theo, nhập dự án của bạn từ GitHub.

image.png

Bây giờ, bạn cần phải cấu hình dự án của mình. Đối với một dự án Next.js, bạn hầu như không cần thực hiện bất kỳ thay đổi nào đối với bản dựng và các thông số khác. Nếu ứng dụng của bạn phụ thuộc vào bất kỳ Biến môi trường nào, bạn cần thêm từng biến một. Trong trường hợp của chúng tôi, chúng tôi có một. Vì vậy, chúng ta hãy thêm nó. Sau đó, bấm vào Deploynút.

image.png

Xin chúc mừng!!! Bạn đã triển khai ứng dụng thành công trên Vercel. Giờ đây, bạn có thể truy cập ứng dụng một cách công khai bằng URL được tạo bởi quá trình triển khai.

image.png

Sau khi triển khai, bạn có thể thực hiện nhiều kiểm tra và cấu hình bổ sung dựa trên nhu cầu của mình. Nếu ứng dụng của bạn có một hoặc nhiều chức năng không có máy chủ, bạn có thể xem nhật ký thực thi trực tiếp từ Functionstab dự án của mình. Hình ảnh dưới đây cho thấy nhật ký cho các chức năng của chúng tôi.

image.png

Tóm tắt

  • Next.jslà tương lai (có thể cho là?) cho các dự án dựa trên React. Nó rất dễ thiết lập, tìm hiểu và sử dụng. Đây tailwindcsslà một thư viện CSS thân thiện với nhà phát triển để tạo kiểu cho ứng dụng. Revuelà một dịch vụ bản tin tuyệt vời.
  • Người dùng của bạn, khách hàng thích onenessbelongingnessSau đó, tại sao không tải dịch vụ bản tin trong chính ứng dụng / trang web và quản lý nó?
  • Next.js APIslà Node.js serverless functionstrong nền. Đó là một cách tuyệt vời để tìm nạp, tương tác với các dịch vụ back-end.
  • Thật dễ dàng để triển khai và duy trì ứng dụng Next.js của bạn (bao gồm cả các chức năng không cần máy chủ) bằng cách sử dụng Vercel.
  • Tương tự như điều này, bạn có thể tích hợp nhiều dịch vụ khác như GitHub, blog của bạn và nhiều dịch vụ khác mà tôi sẽ đề cập trong bài đăng sắp tới của mình.

Liên kết: https://blog.greenTHER.info/create-newsletter-with-revue-nextjs-api-routes-tailwindcss

#nextjs #api #tailwindcss #react #twitter 

What is GEEK

Buddha Community

Cách Tạo Bản Tin Với Twitter Revue, Next.js & Tailwindcss

NBB: Ad-hoc CLJS Scripting on Node.js

Nbb

Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.

Status

Experimental. Please report issues here.

Goals and features

Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.

Additional goals and features are:

  • Fast startup without relying on a custom version of Node.js.
  • Small artifact (current size is around 1.2MB).
  • First class macros.
  • Support building small TUI apps using Reagent.
  • Complement babashka with libraries from the Node.js ecosystem.

Requirements

Nbb requires Node.js v12 or newer.

How does this tool work?

CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).

Usage

Install nbb from NPM:

$ npm install nbb -g

Omit -g for a local install.

Try out an expression:

$ nbb -e '(+ 1 2 3)'
6

And then install some other NPM libraries to use in the script. E.g.:

$ npm install csv-parse shelljs zx

Create a script which uses the NPM libraries:

(ns script
  (:require ["csv-parse/lib/sync$default" :as csv-parse]
            ["fs" :as fs]
            ["path" :as path]
            ["shelljs$default" :as sh]
            ["term-size$default" :as term-size]
            ["zx$default" :as zx]
            ["zx$fs" :as zxfs]
            [nbb.core :refer [*file*]]))

(prn (path/resolve "."))

(prn (term-size))

(println (count (str (fs/readFileSync *file*))))

(prn (sh/ls "."))

(prn (csv-parse "foo,bar"))

(prn (zxfs/existsSync *file*))

(zx/$ #js ["ls"])

Call the script:

$ nbb script.cljs
"/private/tmp/test-script"
#js {:columns 216, :rows 47}
510
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
true
$ ls
node_modules
package-lock.json
package.json
script.cljs

Macros

Nbb has first class support for macros: you can define them right inside your .cljs file, like you are used to from JVM Clojure. Consider the plet macro to make working with promises more palatable:

(defmacro plet
  [bindings & body]
  (let [binding-pairs (reverse (partition 2 bindings))
        body (cons 'do body)]
    (reduce (fn [body [sym expr]]
              (let [expr (list '.resolve 'js/Promise expr)]
                (list '.then expr (list 'clojure.core/fn (vector sym)
                                        body))))
            body
            binding-pairs)))

Using this macro we can look async code more like sync code. Consider this puppeteer example:

(-> (.launch puppeteer)
      (.then (fn [browser]
               (-> (.newPage browser)
                   (.then (fn [page]
                            (-> (.goto page "https://clojure.org")
                                (.then #(.screenshot page #js{:path "screenshot.png"}))
                                (.catch #(js/console.log %))
                                (.then #(.close browser)))))))))

Using plet this becomes:

(plet [browser (.launch puppeteer)
       page (.newPage browser)
       _ (.goto page "https://clojure.org")
       _ (-> (.screenshot page #js{:path "screenshot.png"})
             (.catch #(js/console.log %)))]
      (.close browser))

See the puppeteer example for the full code.

Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet macro is similar to promesa.core/let.

Startup time

$ time nbb -e '(+ 1 2 3)'
6
nbb -e '(+ 1 2 3)'   0.17s  user 0.02s system 109% cpu 0.168 total

The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx this adds another 300ms or so, so for faster startup, either use a globally installed nbb or use $(npm bin)/nbb script.cljs to bypass npx.

Dependencies

NPM dependencies

Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.

Classpath

To load .cljs files from local paths or dependencies, you can use the --classpath argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs relative to your current dir, then you can load it via (:require [foo.bar :as fb]). Note that nbb uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar in the namespace name becomes foo_bar in the directory name.

To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:

$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"

and then feed it to the --classpath argument:

$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]

Currently nbb only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar files will be added later.

Current file

The name of the file that is currently being executed is available via nbb.core/*file* or on the metadata of vars:

(ns foo
  (:require [nbb.core :refer [*file*]]))

(prn *file*) ;; "/private/tmp/foo.cljs"

(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"

Reagent

Nbb includes reagent.core which will be lazily loaded when required. You can use this together with ink to create a TUI application:

$ npm install ink

ink-demo.cljs:

(ns ink-demo
  (:require ["ink" :refer [render Text]]
            [reagent.core :as r]))

(defonce state (r/atom 0))

(doseq [n (range 1 11)]
  (js/setTimeout #(swap! state inc) (* n 500)))

(defn hello []
  [:> Text {:color "green"} "Hello, world! " @state])

(render (r/as-element [hello]))

Promesa

Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core namespace is included with the let and do! macros. An example:

(ns prom
  (:require [promesa.core :as p]))

(defn sleep [ms]
  (js/Promise.
   (fn [resolve _]
     (js/setTimeout resolve ms))))

(defn do-stuff
  []
  (p/do!
   (println "Doing stuff which takes a while")
   (sleep 1000)
   1))

(p/let [a (do-stuff)
        b (inc a)
        c (do-stuff)
        d (+ b c)]
  (prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while
3

Also see API docs.

Js-interop

Since nbb v0.0.75 applied-science/js-interop is available:

(ns example
  (:require [applied-science.js-interop :as j]))

(def o (j/lit {:a 1 :b 2 :c {:d 1}}))

(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1

Most of this library is supported in nbb, except the following:

  • destructuring using :syms
  • property access using .-x notation. In nbb, you must use keywords.

See the example of what is currently supported.

Examples

See the examples directory for small examples.

Also check out these projects built with nbb:

API

See API documentation.

Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.

Build

Prequisites:

  • babashka >= 0.4.0
  • Clojure CLI >= 1.10.3.933
  • Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

  • Clone and cd into this repo
  • bb release

Run bb tasks for more project-related tasks.

Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: https://github.com/borkdude/nbb 
License: EPL-1.0

#node #javascript

Dang  Tu

Dang Tu

1658497701

Cách Tạo Bản Tin Với Twitter Revue, Next.js & Tailwindcss

Tìm hiểu cách tạo bản tin với các API Revue, các tuyến API Next.js và Tailwindcss. Cách tốt nhất để đưa Bản tin vào ứng dụng / trang web Next.js của bạn.

Bạn có một bản tin email hay đang cân nhắc việc bắt đầu một bản tin? Bản tin email cung cấp cho người đăng ký của bạn thông tin cập nhật thường xuyên về công việc, sản phẩm, đam mê, cuộc sống, hành trình của bạn, bất cứ điều gì bạn thấy phù hợp để chia sẻ. Chúng tôi có một số nhà cung cấp / sản phẩm / trang web tuyệt vời giúp chúng tôi bắt đầu ngay với dịch vụ bản tin email. Buttondown, Mailchimp, MailerLite, Substack chỉ là một vài cái tên ở đây.

Đầu năm nay, Twitter thông báo mua lại Revue , một dịch vụ giúp mọi người bắt đầu và xuất bản các bản tin biên tập miễn phí và dễ dàng. Không chỉ vậy. Twitter cũng đã cung cấp các tính năng Pro của Revue miễn phí cho tất cả các tài khoản.

Vài ngày trước, một tweet từ tài khoản chính thức của Revue xác nhận rằng họ sẽ cho phép mọi người đăng ký nhận bản tin Revue của bạn trực tiếp từ hồ sơ Twitter của bạn. Giữ một số cuộc tranh luận sang một bên, tôi nghĩ đó là một động thái tuyệt vời.

Là chủ sở hữu của một bản tin, chúng tôi có thể quảng bá nó theo nhiều cách.

  • Chúng tôi có thể liên kết đến trang bản tin từ trang web, blog của chúng tôi.
  • Chúng tôi có thể nhúng biểu mẫu đăng ký vào trang web của mình bằng cách sử dụng các đoạn mã JavaScript, HTML, CSS đơn giản do nhà cung cấp cung cấp.
  • Cuối cùng, nếu nhà cung cấp bản tin cung cấp API để truy cập dữ liệu, chúng tôi có thể tạo, quản lý bản tin hoàn toàn trong tầm kiểm soát của chúng tôi. Đây là một cách sử dụng mạnh mẽ mang lại cho người dùng của bạn cảm giác onenesslà một phần của cùng một trang web, giao diện tương tự.

Vậy, kế hoạch là gì?

Hướng dẫn này sẽ dạy cách sử dụng các RevueAPI để tìm nạp dữ liệu vào một Next.jsứng dụng bằng cách sử dụng các tuyến API (các chức năng không có máy chủ). Chúng tôi cũng sẽ sử dụng tailwindcssđể cung cấp cho ứng dụng một giao diện đẹp hơn.

Tôi đang trên đường chuyển trang web cũ của mình sang trang web mới bằng cách sử dụng Next.jstailwindcss, và bản tin sẽ là một phần của nó. Vì vậy, đây là một cơ hội tuyệt vời để chia sẻ những gì tôi đã thực hiện và học được.

TL; DR

Nếu bạn muốn chuyển sang ứng dụng cuối cùng hoặc mã nguồn sớm, đây là các liên kết,

Thiết lập Dịch vụ Bản tin bằng Revue

Để thiết lập bản tin với Revue, hãy đăng ký https://www.getrevue.co/ bằng tài khoản Twitter hoặc email của bạn.

Revue Đăng ký

Tiếp theo, đăng nhập vào tài khoản của bạn để thiết lập bản tin bằng cách cung cấp tên, mô tả, bố cục, vấn đề và lịch trình. Bạn có thể tích hợp nhiều dịch vụ như Twitter, Facebook, Instagram với tài khoản Revue của mình để lấy nội dung từ chúng để thêm vào bản tin. Ngoài ra, bạn có thể tìm nạp dữ liệu bằng nguồn cấp dữ liệu RSS. Bạn cũng có thể tích hợp nguồn cấp dữ liệu RSS của blog được hỗ trợ bởi Hshnode của mình. Tôi đã thực hiện điều ước của mình với Sam Sycamore rồi 😆!

Phần cuối của trang tích hợp hiển thị khóa API của bạn để truy cập dữ liệu bản tin qua các yêu cầu HTTP. Vui lòng sao chép chìa khóa này và giữ nó an toàn.

Mã API

Khóa API này sẽ là một phần của Authorizationgiá trị tiêu đề khi sử dụng các API Revue. Đây là liên kết để tìm hiểu về tất cả các API có sẵn công khai. Trong hướng dẫn này, chúng tôi sẽ sử dụng những thứ sau,

  • POST /v2/subscribers: Thêm người đăng ký vào danh sách.
  • GET /v2/subscribers: Trả về danh sách những người đăng ký đang hoạt động của bạn.
  • GET /v2/issues: Trả về danh sách các vấn đề đã gửi của bạn.

Tuy nhiên, trước đó, chúng ta hãy xây dựng giao diện người dùng của ứng dụng Đăng ký Bản tin.

Tạo ứng dụng đăng ký nhận bản tin bằng Next.js và Tailwindcss

Có rất nhiều dự án dành cho người mới bắt đầu có sẵn trong GitHub để bắt đầu với Next.js và Tailwindcss. Yêu thích cá nhân của tôi là next-starter-tailwind vì tính đơn giản của nó. Tôi sẽ sử dụng nó làm mẫu để tạo kho lưu trữ cho ứng dụng đăng ký bản tin. Vui lòng sử dụng bất kỳ dự án khởi đầu nào khác mà bạn cảm thấy thoải mái.

Vui lòng tạo một kho lưu trữ bằng cách nhấp vào Use this templatenút của next-starter-tailwindkho lưu trữ.

image.png

Cung cấp thông tin chi tiết được yêu cầu và tạo kho lưu trữ từ mẫu.

image.png

Bây giờ sao chép kho lưu trữ và duyệt đến thư mục dự án. Mở dấu nhắc lệnh hoặc cửa sổ đầu cuối để cài đặt phần phụ thuộc bằng lệnh sau,

npm install # Or, yarn install

Ở giai đoạn này, vui lòng mở dự án bằng trình soạn thảo mã yêu thích của bạn (Mã VS, trong trường hợp của tôi) và thực hiện các thay đổi mã nhỏ. Mở header.jstệp trong componentsthư mục và tìm Next.js Starter Tailwindvăn bản. Thay đổi văn bản này thành Newsletter demo powered by Next.js Revue Tailwind. Ngoài ra, bạn có thể thay đổi tên người tạo, thông tin GitHub trong footer.jstệp.

Bây giờ, hãy lưu các thay đổi của bạn và sử dụng lệnh này từ dấu nhắc lệnh của bạn để khởi chạy ứng dụng.

npm run dev # Or, yarn dev

Truy cập ứng dụng bằng URL http://localhost:3000. Bạn sẽ thấy giao diện người dùng ban đầu xuất hiện.

Giao diện người dùng ban đầu

Tạo biểu mẫu đăng ký

Hãy tạo một biểu mẫu đăng ký cơ bản với một trường email và một nút để đăng ký. Vui lòng tạo một tệp mới có tên Subscribe.jstrong componentsthư mục với nội dung sau.

const Subscribe = () => {
  return (
    <div className="border border-gray-200 rounded p-6 my-4 w-full bg-gray-50">
      <p className="text-gray-900 mb-6 text-lg md:text-xl">
         Want to keep your brain engaged with great UI/UX learning content?
      </p>
      <p className="text-gray-800 dark:text-gray-400 mb-10 text-base">
        Enter your email address and you'll be be added to my email newsletter, of which you can opt out any time.
      </p>
      <form className="relative my-4">
        <input
          aria-label="Email for newsletter"
          placeholder="john@email.com"
          type="email"
          autoComplete="email"
          required
          className="py-4 px-0 text-md bg-transparent w-9/12 text-gray-900 border-b-2 border-gray-600 dark:border-gray-400 dark:text-white focus:border-brand focus-visible:outline-none"
        />
        <button
          className="flex justify-center px-5 py-4 mt-8 bg-green-600 text-white font-bold text-lg"
          type="submit"
        >
          Subscribe
        </button>
      </form>

      <p className="text-xl text-gray-800 dark:text-gray-200">
        14 subscribers . 3 issues
      </p>
    </div>
  );
};

export default Subscribe;

Nó là một thành phần phản ứng với một biểu mẫu đơn giản có một trường email và một nút. Chúng tôi cũng đã mã hóa số người đăng ký và số vấn đề. Sau đó, chúng tôi sẽ thực hiện các lệnh gọi API để tìm nạp chúng. Chúng tôi đã tạo kiểu cho phần tử HTML bằng cách sử dụng các lớp tailwindcss .

Bây giờ chuyển sang thư mục index.jsbên dưới pages. Thay thế nội dung của tệp bằng nội dung sau,

import Subscribe from "@components/Subscribe";

export default function IndexPage() {
  return (
    <Subscribe />
  );
}

Ở đây, chúng tôi đang nhập và sử dụng Subscribethành phần để khi tải ứng dụng, nó sẽ hiển thị biểu mẫu đăng ký bản tin. Hãy làm mới trang. Bạn sẽ thấy các biểu mẫu đăng ký như,

Mẫu đăng ký

Tạo các tuyến API Next.js để đăng ký và nhiều hơn nữa

Bây giờ đã đến lúc tạo Next.js API Routesđể đăng ký một người đăng ký mới, lấy số lượng người đăng ký và danh sách các vấn đề.

Các chức năng không máy chủ Next.js

Với các Định tuyến API của Next.js , bạn có thể dễ dàng tạo các điểm cuối API. Ở chế độ nền, nó sử dụng các chức năng không máy chủ của Node.js. Bạn cần tạo các chức năng này bên trong pages/apithư mục. Vì vậy, trước tiên chúng ta hãy tạo một thư mục được gọi là apidưới pagesthư mục.

Chúng tôi sẽ cần khóa API Revue ngay bây giờ. Vui lòng tạo .env.localtệp ở thư mục gốc của thư mục dự án với dòng sau,

REVUE_API_KEY=<REPLACE_THIS_WITH_REVUE_API_KEY>

Vui lòng sử dụng của API Keybạn mà bạn đã sao chép từ trang tích hợp thu hồi trước đó.

Ở giai đoạn này, bạn cần khởi động lại máy chủ cục bộ để biến môi trường được tải trong ứng dụng của chúng tôi. Vì vậy, hãy dừng máy chủ và khởi động lại nó bằng yarn devlệnh.

Hãy tạo tuyến API để đăng ký một người đăng ký mới.

Nhưng, cố lên! Tại sao chúng tôi không thể sử dụng API Revue trực tiếp?

Bạn có thể. Có thể sử dụng các API Revue trực tiếp trong các thành phần React của bạn. Tuy nhiên, có một số lợi thế khi sử dụng nó thông qua các API Next.js.

  • Trong tương lai, nếu bạn muốn sử dụng một dịch vụ bản tin khác ngoài Revue, mã thành phần giao diện người dùng của bạn không bao giờ thay đổi. Bạn chỉ cần thay đổi chức năng serverless và triển khai lại.
  • Có một sự trừu tượng. Nó giúp bạn triển khai và lưu trữ riêng API cùng với các trường hợp sử dụng kinh doanh của riêng bạn.
  • Việc truy cập trực tiếp các API này ở phía máy khách sẽ khiến bạn gặp rủi ro về rủi ro API keymà bất kỳ ai cũng có thể lấy được dễ dàng bằng cách kiểm tra các yêu cầu mạng. Bạn không muốn điều đó!

Được rồi, hãy tiếp tục.

Tạo tuyến API Next.js để đăng ký một người đăng ký mới

Tạo một tệp được gọi là thư mục subscribe.jsbên trong pages/api. Điều đó có nghĩa là lộ trình API của chúng tôi sẽ có thể truy cập được từ các thành phần giao diện người dùng bằng cách sử dụng URI /api/subscribe. Vui lòng dán nội dung sau vào subscribe.jstệp.

export default async function handler(req, res) {
    // 1. Get the email from the payload and
    // validate if it is empty.
    const { email } = req.body;
    if (!email) {
        return res.status(400).json({error: 'Please provide an email id.'});
    }

    // 2. Use the Revue API Key and create a subscriber using
    // the email we pass to the API. Please note, we pass the
    // API Key in the 'Authorization' header.
    try {
        const API_KEY = process.env.REVUE_API_KEY;
        const response = await fetch(
            `https://www.getrevue.co/api/v2/subscribers`,
            {
                method: 'POST',
                body: JSON.stringify({email: email, double_opt_in: false}),
                headers: {
                    'Authorization': `Token ${API_KEY}`,
                    'Content-Type': 'application/json'
                }
            }
        )

    // 3. We check in the response if the status is 400
    // If so, consider it as error and return. Otherwise a 201
    // for create        
        if (response.status >=400) {
            const message = await response.json();
            console.log(message.error.email[0]);
            return res.status(400).json({error: message.error.email[0]});
        }
        // Send a JSON response
        res.status(201).json({
            message: `Hey, ${email}, Please check your email and verify it. Can't wait to get you boarded.`,
            error: ''
        });
    } catch (err) {
    // 4. If the control goes inside the catch block
    // let us consider it as a server error(500)  
        return res.status(500).json({error: err.message || error.toString()});
    }
}

Một vài điều đang diễn ra trong chức năng trên.

  1. Khi ai đó gọi hàm API này, chúng tôi mong đợi một phần email của tải trọng. Vì vậy, trước tiên, hãy lấy email từ tải trọng và xác thực nếu nó trống.
  2. Tiếp theo, sử dụng email và API_KEY để gọi API Revue để đăng ký người đăng ký. Lưu ý tải trọng ở đây. Chúng tôi đang chuyển giá trị email và double_opt_ingiá trị như false. Trên thực tế, bạn sẽ KHÔNG chuyển giá trị double_opt_in sai vì bạn muốn người đăng ký của mình xác minh email trước khi xác nhận. Chúng tôi đang làm điều đó chỉ vì lợi ích của bản demo.
  3. Sau đó, chúng tôi kiểm tra responsenếu trạng thái là 400. Nếu vậy, hãy coi đó là một lỗi và quay lại với một thông báo lỗi. Nếu không, 201 để tạo và trả về với thông báo thành công.
  4. Cuối cùng, Nếu điều khiển đi vào bên trong khối bắt, chúng ta hãy coi đó là lỗi máy chủ (500).

Cập nhật mã giao diện người dùng để đăng ký người đăng ký

Chúng tôi sẽ cập nhật Subscribethành phần để sử dụng /api/subscribeAPI. Mở Subscribe.jstệp trong componentsthư mục và thực hiện các thay đổi này.

Nhập useStatehook từ reactđể quản lý một vài trạng thái. Thêm dòng này ở đầu tệp.

import { useState } from 'react';

Tạo ba biến trạng thái để xử lý email từ đầu vào của người dùng và thông báo lỗi, thành công từ lệnh gọi API. Thêm ba dòng này vào đầu Subscribehàm dưới dạng,

const Subscribe = () => {
 const [email, setEmail] = useState('');
 const [error, setError] = useState('');
 const [success, setSuccess] = useState('');
   return (
     ..... 
     {/* Rest of the code as is */}
     ....
   )
}

Tiếp theo, xử lý hai sự kiện. Một là để nắm bắt đầu vào của người dùng trong trường email và thứ hai là xử lý để gửi.

...
...
<form className="relative my-4" onSubmit={subscribeMe}>
     <input
       onChange={changeEmail}

Bây giờ là lúc để xác định cả hai subscribeMechangeEmailcác phương thức.

const subscribeMe = async (event) => {
  event.preventDefault();

  const res = await fetch("/api/subscribe", {
     body: JSON.stringify({ email: email }),
     headers: { 'Content-Type': 'application/json' },
     method: "POST",
  });

 const { error, message } = await res.json();
  if (error) {
     setError(error);
  } else {
     setSuccess(message);
  }
};

const changeEmail = (event) => {
 const email = event.target.value;
 setEmail(email);
}

Trong subscribeMephương thức này, chúng tôi gọi là API /api/subscribe, chuyển giá trị email dưới dạng tải trọng. Sau đó, chúng tôi xử lý lỗi và thông báo thành công.

Cuối cùng, hãy hiển thị thành công và thông báo lỗi trong giao diện người dùng. Thêm mã này ngay sau phần tử biểu mẫu.

{success 
       ? 
    <span className="flex items-center text-sm font-bold text-green-700"> 
         {success}
    </span> 
       : 
    <span className="flex items-center text-sm font-bold text-red-800">
          {error} 
    </span>
}

Tuyệt vời, bây giờ hãy truy cập ứng dụng và cung cấp một id email để đăng ký. Vì chúng tôi đã tắt xác minh email, bạn có thể kiểm tra nó bằng một id email tùy ý. Vui lòng xem toàn bộ tệp nguồn từ đây .

Đăng ký thành công

Để xác minh, địa chỉ email đã được thêm thành công, vào trang người đăng ký trong tài khoản của bạn. Bạn sẽ thấy id email mới này được thêm vào,

Người đăng ký phụ đã được thêm

Hãy đảm bảo sử dụng xác minh email bằng cách bật double_opt_in: truehàm API để sử dụng sản xuất.

Hãy thử lại cùng một id email để cố gắng đăng ký!

đăng ký thất bại

Đúng, bạn sẽ gặp lỗi đó. Đó là tất cả. Đăng ký hoạt động tốt.

Nhận số lượng người đăng ký

Được rồi, hãy tính số người đăng ký. Vì vậy, bây giờ chúng ta sẽ viết một hàm không máy chủ để tìm nạp số lượng người đăng ký. Hãy tạo một tệp có tên subscribers.jsdưới pages/apithư mục với nội dung sau.

export default async function handler(_, res) {
  const API_KEY = process.env.REVUE_API_KEY;
  const response = await fetch('https://www.getrevue.co/api/v2/subscribers', {
    headers: {
      Authorization: `Token ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    method: 'GET'
  });

  const data = await response.json();
  const count = data.length;

  res.setHeader(
    'Cache-Control',
    'public, s-maxage=1200, stale-while-revalidate=600'
  );

  return res.status(200).json({ count });
}

Chúng tôi sử dụng API Revue để tìm nạp danh sách người đăng ký và sau đó trả lại số lượng dưới dạng phản hồi. Vì vậy, bây giờ chúng ta phải sử dụng /api/subscribersURI để tìm nạp số lượng. Hãy làm nó.

Cập nhật mã giao diện người dùng để tìm nạp số lượng người đăng ký

Chúng tôi cần tìm nạp số lượng người đăng ký khi Subscribethành phần tải. Ngoài ra, nếu có người đăng ký mới, chúng tôi cần hiển thị số lượng cập nhật trong giao diện người dùng. Next.jshỗ trợ hai loại pre-rendering,

  • Static Generation(SSG): Trong trường hợp này, mọi thứ đều được biên dịch trước, tạo sẵn và lưu vào bộ nhớ đệm. Bạn không thấy những thay đổi trong nội dung của mình cho đến khi có một bản dựng khác. Nó hoạt động tốt nhất khi bạn xử lý dữ liệu tĩnh như các bài báo trên blog.
  • Server-Side Rendering(SSR): Tại đây, dữ liệu cho một trang được tạo theo yêu cầu cho mỗi yêu cầu.

Chúng tôi muốn tạo tĩnh càng nhiều càng tốt nhưng có thể không tránh được việc hiển thị phía máy chủ trong một số trường hợp. Đối với ứng dụng của chúng tôi, chúng tôi sẽ sử dụng SWR. Như được mô tả ở đây ,

SWRcó nguồn gốc từ stale-while-revalidate, một chiến lược vô hiệu hóa bộ nhớ cache HTTP được phổ biến bởi HTTP RFC 5861. SWR là một chiến lược trước tiên trả lại dữ liệu từ bộ nhớ cache (cũ), sau đó gửi yêu cầu tìm nạp (xác thực lại) và cuối cùng là dữ liệu cập nhật.

Với sự hỗ trợ của Next.js pre-renderingSWR, bạn có thể kết xuất trước trang cho SEO và cho phép lưu vào bộ nhớ đệm, xác thực lại và tìm nạp lại ở các khoảng thời gian ở phía máy khách.

Cài đặt swrthư viện bằng lệnh,

npm install swr #Or, yarn add swr

Thư swrviện cung cấp cho chúng ta một hook được gọi là useSWR. Nó có hai tham số, a keyvà một hàm tìm nạp. Giá keytrị là một chuỗi, thường là URL API mà chúng ta sẽ chuyển cho fetcherhàm và fetcherhàm có thể là một hàm không đồng bộ. Vì vậy, chúng ta hãy tạo một hàm tìm nạp đơn giản.

Vui lòng tạo một utilsthư mục ở thư mục gốc của dự án và tạo một fetcher.jstệp có nội dung sau,

export default async function Fetcher(...args) {
 const res = await fetch(...args);

 return res.json();
}

Tiếp theo, trong components/Subscribe.jstệp, hãy bao gồm hai lần nhập này.

import useSWR from 'swr';
import fetcher from '../utils/fetcher';

Bây giờ chúng ta có thể sử dụng useSWRhook để chuyển API ( api/subscribers) và hàm tìm nạp.

const Subscribe = () => {

  const [email, setEmail] = useState('');
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  // --- above is old code ---

  const { data } = useSWR('/api/subscribers', fetcher);
  const subscriberCount = data?.count;

Xin lưu ý, chúng tôi sử dụng JavaScript optional chaining(?.)tính năng để lấy giá trị đếm. Nó xử lý undefinedgiá trị một cách an toàn.

Mỗi khi dữ liệu được thay đổi ở phần cuối, subscriberCountbiến sẽ có số lượng mới nhất.

Cuối cùng là sử dụng subscriberCountbiến trạng thái thay vì giá trị được mã hóa cứng.

<p className="text-sm text-gray-800 dark:text-gray-200">
  { subscriberCount } subscribers . 3 issues
</p>

Đó là tất cả. Làm mới ứng dụng và xem phản ánh số lượng thực tế.

Số lượng người đăng ký

Nhận danh sách vấn đề

Bây giờ chúng ta cần lấy danh sách vấn đề và số lượng các vấn đề đã xuất bản. Vì vậy, chúng ta phải viết lại một hàm serverless để tìm nạp các chi tiết này. Nhưng chờ đã, tôi sẽ không làm điều đó trong hướng dẫn này. Hãy xem nó như một bài tập để thử sức.

Gợi ý: Bạn cần sử dụng API Revue này để tìm nạp dữ liệu => GET /v2/issues. Nếu bạn cần trợ giúp, mã API có ở đây và các thay đổi thành phần ở đây để tham khảo.

Cuối cùng, giao diện người dùng phải có số lượng vấn đề thực tế và danh sách các vấn đề đã xuất bản như thế này (tôi có một vấn đề thử nghiệm).

trang cuối cùng

Hãy triển khai

Xin chúc mừng!!! Ứng dụng đã sẵn sàng để sử dụng. Nhưng, nó chỉ có sẵn với bạn. Hãy triển khai nó một cách công khai. Chúng tôi sẽ sử dụng nền tảng Vercel để triển khai ứng dụng của mình. Việc triển khai ứng dụng Next.js trên Vercel rất dễ dàng bằng một vài bước đơn giản. Để điều đó xảy ra, vui lòng cam kết và đẩy tất cả các thay đổi mã của bạn vào GitHubkho lưu trữ.

Tạo tài khoản với Vercel, đăng nhập và nhấp vào New Projectnút để bắt đầu.

image.png

Tiếp theo, nhập dự án của bạn từ GitHub.

image.png

Bây giờ, bạn cần phải cấu hình dự án của mình. Đối với một dự án Next.js, bạn hầu như không cần thực hiện bất kỳ thay đổi nào đối với bản dựng và các thông số khác. Nếu ứng dụng của bạn phụ thuộc vào bất kỳ Biến môi trường nào, bạn cần thêm từng biến một. Trong trường hợp của chúng tôi, chúng tôi có một. Vì vậy, chúng ta hãy thêm nó. Sau đó, bấm vào Deploynút.

image.png

Xin chúc mừng!!! Bạn đã triển khai ứng dụng thành công trên Vercel. Giờ đây, bạn có thể truy cập ứng dụng một cách công khai bằng URL được tạo bởi quá trình triển khai.

image.png

Sau khi triển khai, bạn có thể thực hiện nhiều kiểm tra và cấu hình bổ sung dựa trên nhu cầu của mình. Nếu ứng dụng của bạn có một hoặc nhiều chức năng không có máy chủ, bạn có thể xem nhật ký thực thi trực tiếp từ Functionstab dự án của mình. Hình ảnh dưới đây cho thấy nhật ký cho các chức năng của chúng tôi.

image.png

Tóm tắt

  • Next.jslà tương lai (có thể cho là?) cho các dự án dựa trên React. Nó rất dễ thiết lập, tìm hiểu và sử dụng. Đây tailwindcsslà một thư viện CSS thân thiện với nhà phát triển để tạo kiểu cho ứng dụng. Revuelà một dịch vụ bản tin tuyệt vời.
  • Người dùng của bạn, khách hàng thích onenessbelongingnessSau đó, tại sao không tải dịch vụ bản tin trong chính ứng dụng / trang web và quản lý nó?
  • Next.js APIslà Node.js serverless functionstrong nền. Đó là một cách tuyệt vời để tìm nạp, tương tác với các dịch vụ back-end.
  • Thật dễ dàng để triển khai và duy trì ứng dụng Next.js của bạn (bao gồm cả các chức năng không cần máy chủ) bằng cách sử dụng Vercel.
  • Tương tự như điều này, bạn có thể tích hợp nhiều dịch vụ khác như GitHub, blog của bạn và nhiều dịch vụ khác mà tôi sẽ đề cập trong bài đăng sắp tới của mình.

Liên kết: https://blog.greenTHER.info/create-newsletter-with-revue-nextjs-api-routes-tailwindcss

#nextjs #api #tailwindcss #react #twitter 

Eva  Murphy

Eva Murphy

1625674200

Google analytics Setup with Next JS, React JS using Router Events - 14

In this video, we are going to implement Google Analytics to our Next JS application. Tracking page views of an application is very important.

Google analytics will allow us to track analytics information.

Frontend: https://github.com/amitavroy/video-reviews
API: https://github.com/amitavdevzone/video-review-api
App link: https://video-reviews.vercel.app

You can find me on:
Twitter: https://twitter.com/amitavroy7​
Discord: https://discord.gg/Em4nuvQk

#next js #js #react js #react #next #google analytics

Landen  Brown

Landen Brown

1626084960

Building an Authentication Flow with Next.js, TailwindCSS, & AWS Amplify - OAuth & Email..

In this video I build a custom authentication flow from scratch in a Nextj.s app using AWS Amplify, TailwindCSS. We implement email + password flow as well as sign in with Facebook and Google.

The code for this app is located here: https://github.com/dabit3/next.js-tailwind-authentication

0:00 - Introduction
1:05 - Project setup
3:55 - Creating OAuth Client
5:57 - Creating Facebook OAuth App
6:40 - Creating authentication service on AWS
8:43 - Adding navigation
11:14 - Adding a profile view
13:38 - Configuring redirect URIs
17:10 - Testing the OAuth providers
24:12 - Creating the sign in screen
38:23 - Creating the social sign in screen
45:06 - Creating a reusable Input component
46:00 - Creating the sign in form
52:20 - Creating the sign up form
55:25 - Creating the MFA confirmation screen
58:11 - Creating the forgot password and forgot password submit screens
1:12:02 - Fixing bugs
1:19:28 - Adding a protected route
1:24:00 - Enabling SSR support
1:28:45 - Implementing the Amplify UI component
1:32:53 - Conclusion

#tailwindcss #aws amplify #next #next.js

Eva  Murphy

Eva Murphy

1625751960

Laravel API and React Next JS frontend development - 28

In this video, I wanted to touch upon the functionality of adding Chapters inside a Course. The idea was to not think much and start the development and pick up things as they come.

There are places where I get stuck and trying to find answers to it up doing what every developer does - Google and get help. I hope this will help you understand the flow and also how developers debug while doing development.

App url: https://video-reviews.vercel.app
Github code links below:
Next JS App: https://github.com/amitavroy/video-reviews
Laravel API: https://github.com/amitavdevzone/video-review-api

You can find me on:
Twitter: https://twitter.com/amitavroy7​
Discord: https://discord.gg/Em4nuvQk

#next js #api #react next js #next #frontend #development