DP
Library-Type Site for a Collection of Texts

Making a Library-Type Site for a Collection of Texts


In this post I wanted to describe an example project at a high level and talk about one possible approach to designing and creating a small site. One of the reasons for it is that I recently saw Google’s new tool — Stitch. At the time of writing this it’s in beta version state and may not be available everywhere, but there are most likely other similar tools, so we can consider it as a potential example. Stitch is generally an agent for creating designs and prototypes for a site or app and can provide you with mockups, color palettes, fonts, and even initial code. So, let’s talk about how this can be applied to making a site.

As always, I’m not looking for a one-size-fits-all solution and some optimal approach. I simply had an initial idea and functionality for a site and decided to create its design using Google Stitch.

Initial Setup

At the start I had the basic version of a site made with React, React Router, and plain CSS (without most of the styling). It was supposed to be a simple site to display a number of posts with functionality for searching/filtering, sorting, and loading more posts: a main “Home” page with a list of posts, individual pages for the full texts, and “About” page (here is the GitHub repo).

I wasn’t aiming to add a content management system, but also wanted to leave room to add one in the future, so I tried making it with this functionality in mind. Initially I stored the data (posts content) in a JSON file which I then imported for each individual post display. As I was planning a possible API integration later on, I structured it close to what you normally get while fetching data from an API (array of objects with IDs, slug, titles, dates, texts and so on). As I had two main places to display that data (“Home” page for all posts display and individual pages for each post), I decided to have two separate JSON files: one for basic information on each post and another one for the posts full texts.

I also created separate fetch functions (for both of these files) so I could use them locally first and later swap them for proper API calls. Here is an example of one of the functions:

export async function fetchPosts() {
  if (USE_LOCAL_DATA) {
    const posts = samplePosts.map((post) => ({
      ...post,
      image: post.image ?? postImages[post.slug] ?? null,
    }));

    return Promise.resolve(posts);
  }

  const res = await fetch(POSTS_API_URL);

  if (!res.ok) throw new Error("Could not fetch posts.");

  return res.json();
}
  • If variable the USE_LOCAL_DATA is true, a local sample file is used in a way similar to a fetch request (that’s why it returns a promise).
  • If USE_LOCAL_DATA is false, a normal fetch request is being made and then JSON data can be accessed and used further.

This approach might look a bit strange, but the goal was to start with local files for content, then potentially move them somewhere outside (like simply deploying through any service like Vercel or Netlify), and later on decide whether a completely separate API is needed.

Based on this approach, I also started preparing the JSON file in the following way:

[
  {
    "id": 1,
    "slug": "post-one",
    "title": "Post One",
    "date": "2026-01-15",
    "excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    "author": "Author One",
    "tags": ["tag1", "tag2"],
    "content": "**Lorem** ipsum *dolor* sit amet, consectetur adipiscing elit.\n\n Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
  },
  {
    "id": 2,
    "slug": "post-two",
    "title": "Post Two",
    "date": "2026-02-15",
    "excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    "author": "Author Two",
    "tags": ["tag3", "tag4"],
    "content": "**Lorem** ipsum *dolor* sit amet, consectetur adipiscing elit.\n\n Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
  }
]

Having a local JSON file allows for faster iteration at the beginning (without the need to set up the backend) and makes testing easier, hence I’ve decided to use it first.

Once that structure and functionality had been implemented, I moved on to using Google Stitch to create a design for the site.

Design & Style

I decided not to simply create a prompt with a description of the site and what it should look like. I was interested in how much of the code structure the agent could analyze, so after giving a brief introduction and explaining what the project is, I also pasted the main code parts directly into Google Stitch chat. Basically, I wanted to see if it could tailor the design specifically to my code and not just provide mockups.

After downloading the images, there is also a markdown file with the text content and an HTML file with the code (in my case I specified that I want to use Tailwind CSS).

Having the design, I briefly checked the code and, as it wasn’t a complete one-to-one match with mine, decided to take it a step further: I used another AI to help combine my initial code with the new design to have a workable version (I think any AI tool can be fine to use, for this example I was using Perplexity). To clarify, by a one-to-one match I mean mixing the new design with the initial version so they would work well (ideally, AI should be used for assistance and not to fully replace the core idea/functionality/style/etc.).

Tweaking & Polishing

By that point I had the initial version of the site: functionality and design were implemented and the goal was to adjust everything properly so that it would look and work as intended.

I guess this is the phase that in the current development conditions requires the most of the human touch. For example, this relatively small project can be divided into a setup + prototyping phase, a design creation + implementation phase, and a polishing + improvement phase. Among them: the first one is partially coding, partially prompting; the second one is mostly prompting and copying the provided design; the third one is mostly making your own adjustments and some occasional prompting to get new parts of code or to rewrite the existing ones.

This version is simplified and tailored to what was needed for my specific case: there is no login/account managing functionality at this time, less pages and sharing options, and the styling of the home page has been made more straightforward with only one card looking different from the list (featured post). As always, there are also many minor changes and adjustments that probably won’t be noticed by anyone else except me (so I won’t describe them of course), but I just like tweaking some minor things (especially as someone who is bothered by such things as padding inconsistency when hovering over a tab close button in Chrome and not centered letter in YouTube default profile picture).

Overall, it feels like at the moment, if you choose to use AI when coding, this last phase might be the most important one, as here you need to make sure that everything functions properly and looks the way you wanted it from the beginning. And that is something I wanted to talk about lastly.

Closing Thoughts and Observations

As mentioned earlier, I focused mostly on describing the general structure and approach to making a site like this, without diving into too many details. There are a few reasons for that. First, I’ve used some code from my other projects (filtering and sorting mechanic, cards display, overall layout and some of the shared components). Also, using AI tools allows you to get the necessary parts adjusted to your own goals, hence I wasn’t aiming at showing everything they provided, but instead tried to describe how I did it for a specific task. Lastly, I wanted to talk about such an approach in general, as it can be adapted to each case. Basically, it may be divided into the following parts:

  • You set your initial goal (what you’re building, what the main functionality and features are, what stack you are going to use).
  • You create the basic version (minimal styling, core functionality with some future-proofing and parts of code that can be tweaked/changed easily later on).
  • You work on the design and style of the site or app. Yes, this may look like it should happen earlier, but I’m not aiming at following best practices here. Quite often we have ideas for a certain thing we want to create and we just want to dive into developing it, leaving design to a later stage. While in general this may not be the best idea, if you decide to use AI tools (Google Stitch in the current example) and if you are fine with the fact that the design may look at least somewhat generic (which is not necessarily a bad thing in every scenario), I think you can sometimes use this approach. Obviously, if you plan on having a specific and personalized style, then you have to design everything much earlier and do most of the work yourself.
  • Finally, you fix all the minor issues, tweak everything to your liking, and make sure that it is all working as you initially planned it (once again, for this approach, this could be the most crucial part).

One other detail I would like to mention is that I’m beginning to aim for using fewer third-party solutions (mostly talking about installing additional packages). For a bigger project, this may be rather hard to achieve, but for smaller ones quite a few things can be implemented without any specific additions. For example, I added icons as SVG images that I created locally, without any third-party icons library. And I also used the standard fetch function instead of Axios (not so much because of the recent issues with the package, mostly because I think the basic approach is slightly clearer for a small project). I’ve used React Markdown for text formatting, but at some point I realized that for this site, I only needed two main types of formatting (italic text and paragraph separation) and, instead of using the package, both of them could simply be added by writing a small function that would check the text for new lines and italic characters in the JSON file content (although, with this approach, you may eventually need more options and then either have to install a package like React Markdown or keep adding more and more logic to your formatting function). The bottom line is that manual handling is fine for a smaller project, while utility libraries provide a more robust option when content grows and becomes more complex.


This was a high-level overview of the library-type site I made for storing a collection of texts. Once again, I mostly focused on describing one possible approach to building something like this and also added some observations about the tools and techniques used.

This might be a viable solution for small content sites, prototypes, or projects where you prefer to start with local data and later move to API-driven content.

At the same time, this may not be a good fit for situations where you need complex content editing, frequent updates (especially backend-related), or some level of collaboration with other developers.

Hopefully, this might be helpful when you work on a project like this.


P.S.: I might deploy this site at some point. In that case, if needed, the link could be found in the repository I mentioned earlier in this text.


Some additional details about making this site can be found in this post on my Medium blog.

Thank you for reading.


View my 200+ posts on Medium

I write every Friday and share what I work on and learn.

@Dimterion
Visit my blog