digitalsanity / Next.js-Strapi-Blog

Static blog with Next.js + Strapi Headless CMS

Home Page:https://brave-northcutt-60bde9.netlify.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Next.js Blog with Strapi

Static demo blog. Deployed on Netlify.

Features:

  • static
  • responsive
  • mobile first
  • built with Strapi Headless CMS
  • Strapi uses MongoDB Atlas as database
  • images stored on Cloudinary
  • Strapi deployed on Heroku
  • autocomplete search
  • search results with highlighted match (native)
  • sound
  • dark mode with autodetect system preference and saved user's choice in LocalStorage
  • hamburger menu for mobile layout
  • "Load More" pagination
  • SEO-friendly article list initially fetched on server-side (paginated - client-side)
  • progressive featured images
  • categories
  • like\share\tweet buttons, comment section

How did I do...

Search with highlighted results
  1. When user enters value, we grab its' changes.
  2. Search happens onSubmit.
  3. It's important not to use Next.js's dynamic routes here, because blog would not be static if we'd have pages, depending on user's request (but if you're OK with hybrid/dynamic blog, than it's alright to use them (btw, maybe optional catch all routes will somehow work with static site too, but I haven't tested it)). Instead we go to search page with query passed through "?" sign, here.
  4. Search page will fetch Strapi's API and will render the filtered results based on query parameter.
  5. In search result we convert markup to html and html to text.
  6. We divide text into array based on value match and create new text as array with "mark" tag around match.
  7. Then in useEffect, initially and every time the search value gets changed, we look for "mark" tags in text and cut the text around the first match (or just write "no match" if there is no match). The namings should be self-explanatory here.
  8. It's important to wrap the text inside "p" tag with, for example, "span" tag to avoid React NotFoundError, which occurs when we re-render page (here: search for the second time) after manipulating the DOM (highlighting). Explained here.
  9. Last important thing: when we search for the second time and if in search result list we got result that was in the previous list (but with different match this time) then it will reflect previous highlighted match, which is not what we want. To avoid this we must remove old results and load new when we search. We can do this by triggering re-fetch - this will cause "isValidating" parameter to change on every search, replacing previous results with skeleton load and then load new results with correct highlighted match.
Pagination
  1. Featured articles are fetched on server-side as usual for SEO.
  2. We fetch paginated data on client-side with useSWRInfinite.
  3. We use "size" and "setSize" parameters to change page index.
  4. But instead of page index Strapi's API has Start param pointing at index from which data should be fetched and Limit param.
  5. In getKey function "pageIndex" parameter is the "size" parameter. It always starts with 0.
  6. We set limit param to 1 (fetch 1 article), start param - to "pageIndex + 7" (because first 7 artciles are already fetched on server-side).
  7. On every time user clicks "Load More" button, we increase size param to amount of times we need to fetch 1 artcile in one click (here we need 4, which depends on desktop layout).
  8. We also have to set initialSize parameter to 0, because we don't need paginated data initially, only on demand.

What did I use to make this demo:

Notes:

About

Static blog with Next.js + Strapi Headless CMS

https://brave-northcutt-60bde9.netlify.app


Languages

Language:JavaScript 100.0%