Category Archives: Web

Deploying your static web site to AWS

Nowadays, if you’re developing a static web site, the old hosting packages you’d get via the web hosting companies now need to compete with offerings from the cloud. Azure, AWS and GCP all offer the ability to host your static pages and ofcourse, why wouldn’t they, it’s just storage and ingress to a web server and depending upon your site requirements, these can be hosted for free.

In this post I’m going to deploy a simply little React app using Material UI that I have, I deployed the same to Azure a long while back (it’s available via https://www.mycountdown.co.uk/). It’s a bit of fun which displays a single countdown to a selected date/time and tells you the number of days, minutes etc. and work days.

  • Go to your AWS console and I’m clicking the Host a static web app option in the Build a solution section of the AWS console
  • I then select GitHub from the From your existing code screen as GitHib is where I host the code for the app.
  • AWS wants permissions to my repo. so I’ll authorize that
  • Next I’m going to only Install & Authorize the one repo. with the countdown code, so I select Only select repositories but select All repositories if you prefer
  • As mentioned, I clicked Only select repositories then I selected my countdown app repo. and finally I click Install & Authorise
  • You may be prompted for further authentication from GitHub, oddly AWS said authentication failed when I was doing this and then AWS changed it’s mind and said it was successful

If all works you’ll be back at AWS in the Add repository branch section. We authorized use of a repo. but may have authorised all repos., so now we choose the the repo. and branch to deploy.

  • When ready click Next
  • Fill in anything required on the next page and then click Next again
  • On the review page, reviews your details and then click Save and deploy when ready

If all goes well you’ll see a message regarding AWS downloading the app. and the site will be provisioned. We now need to wait on AWS to Build and move the progress on to the Deploy step. Once completed you’re site will have been provisioned, built and deployed. A Domain URL is assigned and clicking on this, you should see your site.

Starting out with web components

Introduction

Web components are analogous to self-contained controls or components as you’ll have seen in Windows Forms, WPF etc. They allow developers to package up style, scripts and HTML into a single file which also is used to create a custom element, i.e. not part of the standard HTML.

Sadly, still not yet available in all browsers (although I believe Polyfills exist for the main ones). Hence, for this post you’ll either need a polyfill or the latest version of Google Chrome (which I’m using to test this with).

What does it look like using web components?

To start with we create an HTML file for our web component, we then define the template for the component – this is basically the combination of style and the control’s HTML. Finally we write scripts to effect the shadow DOM by interacting with our web component.

In this post we’re going to create a simple little web component which will flash it’s text. Before we look at the component code let’s see the component in use within the following index.html file

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Web Component Test</title>
    <link rel="import" href="flashtext.html">
</head>
<body>
   <flash-text data-text="Hello World"></flash-text>
</body>
</html>

The key points here are that we include the web component using the line

<link rel="import" href="flashtext.html">

and then we use the custom element flash-text with it’s custom attributes and we use the component like this

<flash-text data-text="Hello World"></flash-text>

It’s important to note the closing element, a self closing element is not correctly handled (at least at this time using Google Chrome) and whilst the first usage of a web component might be displayed, if we had several flashing text components in the index.html it’s possible only one would be displayed and no obvious error or reason for the other components not displaying.

Creating our web component

We already decided our component will be stored in flashtext.html (as that’s what we linked to in the previous section).

To start off with, create the following

<template id="flashTextComponent">
</template>
<script>
</script>

We’ve created a new template with the id flashTextComponent. This id will be used within our script, it’s not what the pages using the component uses. To create a new custom element by adding the following to the script

var flashText = document.registerElement('flash-text', {
});

But we’re getting a little ahead of ourselves. Let’s instead create some styling and the HTML for our component. Within the template element, place the following

<style>
   .flashText {
      float: left;
      width: 152px;
      background-color: red;
      margin-bottom: 20px;
   }

   .flashText > .text {
      color: #fff;
      font-size: 15px;
      width: 150px;
      text-align: center;
   }

</style>
<div class="flashText">
   <div class="text"></div>
</div>

The style section simply defines the CSS for both the flashText div and the text div within it. The div elements create our layout template. Obviously if you created something like a menu component, the HTML for this would go here with custom attributes which we’ll define next, mapping to the template HTML.

Next up we need to create the code and custom attributes to map the data to our template. Before we do this let’s make sure the browser supports web components by writing

var template = document.createElement('template');
if('content' in template) {
   // supports web components
}
else {
   // does not support web components
}

If no content exists on the template, Google Chrome will report the error in the dev tools stating content is null (or similar wording).

Within the // supports web components section place the following

var ownerDocument = document.currentScript.ownerDocument;
var component = ownerDocument.querySelector('#flashTextComponent');

var templatePrototype = Object.create(HTMLElement.prototype);

templatePrototype.createdCallback = function () {
   var root = this.createShadowRoot();
   root.appendChild(document.importNode(component.content, true));

   var name = root.querySelector('.text');
   name.textContent = this.getAttribute('data-text');

   setInterval(function(){
      name.style.visibility = (name.style.visibility == 'hidden' ? '' : 'hidden');
   }, 1000);
};

var flashText = document.registerElement('flash-text', {
    prototype: templatePrototype
});

Let’s look at what we’ve done here. First we get at the ownerDocument and then locate our template via it’s id flashTextComponent. Now were going to create an HTMLElement prototype which will (in essence) replace our usage of the web component. When the HTMLElement is created we interact with the shadow DOM placing our component HTML into it and then interacting with parts of the template HTML, i.e. in this case placing data from the data-text custom attribute, into the text content of the div text.

As we want this text to flash we implement the script for this and attached to the visibility style of the text.

Finally, as mentioned previously, we register our custom element and “map” it to the previously created prototype.

Using in ASP.NET

ASP.NET can handle static pages easily enough, we just need to add the following to the RouteConfig

routes.IgnoreRoute("{filename}.html");

Now, inside _Layout.cshtml put in the head section

and within the Index.cshtml (or wherever you want it) place your custom elements, i.e.

<flash-text data-text="Hello World"></flash-text>

References

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
https://developers.google.com/web/fundamentals/web-components/customelements
https://www.webcomponents.org/
https://stackoverflow.com/questions/45418556/whats-the-reason-behind-not-allowing-self-closing-tag-in-custom-element-in-spec

Code for this post

https://github.com/putridparrot/blog-projects/tree/master/webcomponent