Handling page interactivity with ease, retrieving data from the server without a necessary page reload, and updating a website via asynchronous requests are some of the selling points and promises of Single Page Applications.
A web application that is composed of one web page and handles the request for other pages through AJAX and automatically replaces the view with the new page response. As a result of this, the single-page applications are very responsive with improved speed.
To further explore some of the benefits of a single-page application, in this tutorial, I will show you how to easily build a SPA using Angular.
Warning
This guide contains code examples for an older version of Sanity Studio (v2), which is deprecated.
Angular is a JavaScript framework written entirely in TypeScript. Open sourced and maintained by Google, it provides a standard and opinionated structure for building a web application irrespective of the size and complexity.
Its primary purpose is to develop single-page applications and with benefits such as custom components, data binding, and dependency injection, it has helped developers across the globe boost efficiency and performance when building web applications.
What we’ll build
In this guide, we will build a movie application to show some best-selling movies and A-list actors in Hollywood. To manage the contents from the backend we will use Sanity.io and leverage Angular to build the user interface of the application. Once we are done, the application will look similar to the image shown below:
Prerequisites
For this project, you need:
Familiarity with TypeScript
Basic knowledge of building applications with Angular
We will begin by using the Angular CLI to create a new Angular application. Issue the following command from the terminal to do that:
ng new spa-sanity-angular
First, the preceding command will require you to answer a couple of questions as shown here:
Add Angular routing and select CSS as the preferred stylesheet. Once you are done, Angular CLI will create a new basic Angular project in a folder named spa-sanity-angular within your development directory.
Next, navigate into the new project and run the application using the following commands:
//move into the project
cd spa-sanity-angular
// Run the application
ng serve
You can view the default homepage of a new Angular project on http://localhost:4200.
Now that we have created a new Angular application, stop the project from running using CTRL + C and hit enter to proceed. In the next section, we will set up the backend for the project using Sanity studio.
Creating the Sanity backend
To start a new Sanity project, ensure that you have installed the Sanity CLI and run the following command from the spa-sanity-angular folder:
sanity init
When prompted to provide some information. Proceed as follows:
Select the Create new project option
Name the project sanity_ng_movies
Use the default dataset configuration (press Y)
Select the project output path as sanityngmovies
Select the movie project (schema + sample data) option. Using the arrow keys, navigate to that option and press enter when it turns blue.
Upload a sampling of sci-fi movies to your dataset on the hosted sanityngmovies (press Y)
The Sanity CLI will bootstrap a project from the movie template, link the needed dependencies and populate your new sanity studio with some science fiction movies data.
Once the process is completed, you can run your studio. To do that, open a new terminal, move into the sanityngmovies folder and start the studio using the commands below:
By default, a development server such as the Angular app will not be allowed to connect or communicate with the project API in the sanity studio (http://localhost:3333). To change that, we need to add the URL where our Angular application will be served to the permitted origins. Visit https://www.sanity.io/manage and click on the Sanity project that we are working on (sanity_ng_movies)
Next, click on the Settings → API and add http://localhost:4200/ to the CORS origins field. Click on the Save button to proceed. Leave the checkbox marked ‘Allow credentials’ unchecked.
Sourcing Sanity’s Data From Angular
In this section, we will set up the structure that will allow the Angular frontend query and fetch data from Sanity studio created earlier.
To begin, we will need to install the required Sanity Client package for proper interaction in our Angular project. Issue the following command from the terminal within the root of the project:
npminstall @sanity/client @sanity/image-url
Creating an Angular service to retrieve Sanity data
The existing structure of Angular allows separation and abstraction of business logic to a different object regularly referred to as Angular Service. This helps reduce the need to write complex logic within any component and encourages the separation of concerns.
To proceed, we will create an Angular service to retrieve the list of Movies and Actors using the following command:
ng generate service service/sanity
This will create a new folder named service and two new files within it. Open the sanity.service.ts file and replace its content with the following:
First, we created a property sanityClientCredentials which uses the Sanity client package to specify the projectId for the backend created in Sanity studio. Kindly replace the YOUR_PROJECT_ID placeholder with your Project ID, which you can get by navigating to sanityngmovies/sanity.json file or visit https://www.sanity.io/manage and click on the project to view its full details including the Project ID.
Next, we created two asynchronous methods:
getMovies(): Here, we make a GROQ request to the Sanity API to retrieve the lists of movies, showing only the title, released date, poster and overview.
getActors(): Similar to the first method, this also made a GROQ request to retrieve the lists of actors from the Sanity API.
Lastly in this section, to be able to reference the installed sanity module with ECMAScript imports/exports, we need to turn on the allowSyntheticDefaultImports flag within tsconfig.json file. This is a known issue and can easily be fixed. To proceed, open tsconfig.json file and update the “compilerOptions” object by including:
Within the SanityService created in the preceding section, we referenced two files named actor.ts and movie.ts. These are interfaces that help to identify the datatypes of each of the properties expected to be returned by the methods defined in Sanity Service.
To set up these files, create actor.ts and movie.ts within the app folder and populate each one as shown below:
From the code snippet above, we injected the SanityService via the constructor and defined a sanityService property to identify it. Next, we created a getMovies() method to retrieve the movies from the service.
Next, open the app/movies/movies.component.html and replace its content with:
<!-- src/app/movies/movies.component.html --><divclass="container content-wrapper"><div*ngFor="let movie of movies"class="card"><imgsrc="{{ imageUrl(movie.poster).width(200).url() }}"alt="{{ movie.title }}"/><divclass="card-body"><h5class="card-title">
{{ movie.title }}
</h5><pclass="card-text"*ngFor="let view of movie.overview">
{{ view["children"][0]["text"] }}
</p><div>{{ movie.releaseDate | date }}</div></div></div></div>
We iterate over the list of movies and render the list in HTML.
Creating the Actors component
To create the Actors component, issue the following command from the terminal:
ng generate component actors
This command will create an actors folder with the following files in it:
A component file, (actors.component.ts)
A template file ( actors.component.html)
A CSS file, (actors.component.css)
A testing specification file, actors.component.spec.ts
Open app/actors/actors.component.ts and use the following content for it:
In this component, we injected the sanity service and created a getActors() to retrieve the list of Actors from the Sanity API.
With that in place, we can now access the actors property from the template file. To do that, open the app/actors/actors.component.html and replace its content with:
<!-- src/app/actors/actors.component.html --><divclass="container content-wrapper"><div*ngFor="let actor of actors"class="card"><imgsrc="{{ imageUrl(actor.image) }}"alt="{{ actor.name }}"/><divclass="card-body"><h5class="card-title">
{{ actor.name }}
</h5></div></div></div>
This snippet renders the list of A-list actors as retrieved from the API listing the names and images of each Actor.
Setting up Routing
Earlier when we created the Angular application, we selected an option to automatically add the Angular routing module. This was created by the Angular CLI and all that is required is to reference the components created and define respective paths.
Open app/app-routing.module.ts and paste the following content in it:
Finally, open the app/app.component.html file and replace its content with the following:
<!-- src/app/app.component.html --><divclass="container"><div><spanclass="navbar-brand"href="#">SPA Angular + Sanity </span></div><navclass="navbar navbar-expand-lg navbar-light bg-light"><divclass="collapse navbar-collapse"id="navbarNav"><ulclass="navbar-nav mx-auto"><liclass="nav-item"><arouterLink="/movies"class="nav-link active">Movies</a></li><liclass="nav-item"><arouterLink="/actors"class="nav-link">Actors</a></li></ul></div></nav><divclass="jumbotron"><h4class="display-4">Best Selling Movies and A-List Actors</h4></div><router-outlet></router-outlet></div>
Here, we defined the layout and include the navigation bar with respective links.
Testing the application
Now you can run the application again with:
ng serve
If you encounter the following errors:
This error occurred because TypeScript doesn’t know classes from Node.js by default, you will need to install the type definitions for Node.js. To begin, First, you need to install types/node:
npminstall --save @types/node
Once the installation is completed, open tsconfig.app.json file and update the “compilerOptions” object as shown here:
Lastly to handle the warning from the terminal about @sanity/client. Open angular.json file and update the options object defined within the build as shown below:
In this guide, we successfully built a single-page application with Angular and Sanity. We created an Angular service with methods to retrieve data from Sanity API and render the contents with Angular. Feel free to improve on this application by updating the GROQ request to fetch more content from the Sanity API.
The complete source code for the project built in this guide can be found here on GitHub. I hope you found this guide very helpful. Happy Coding!
Sanity Composable Content Cloud is the headless CMS that gives you (and your team) a content backend to drive websites and applications with modern tooling. It offers a real-time editing environment for content creators that’s easy to configure but designed to be customized with JavaScript and React when needed. With the hosted document store, you query content freely and easily integrate with any framework or data source to distribute and enrich content.
Sanity scales from weekend projects to enterprise needs and is used by companies like Puma, AT&T, Burger King, Tata, and Figma.
Guide to server-side rendering with Deno and React
Studio v2
In this tutorial, we will take a look at server-side rendering with Deno and React. To get a proper hang of the fundamental concepts, we will start by discovering what Deno is, and how it compares to Node in terms of security, package management, and so on.