Having a responsive website is no longer enough. Your audience expects a seamless and personalized customer experience across all their devices—the age of headless technology is coming.
Headless CMS is the next generation in content management for brands that want to stay ahead of the curve by engaging customers through the growing number of channels.
Download The Ultimate Guide to Headless CMS ebook for a deep look into what headless CMS is, and why it should be at the top of your list when choosing a new CMS.
The issue is that the only way for elements to participate in the same CSS grid together (or flexbox for that matter) is for them to be siblings. So, in some cases we might be incentivized to forego HTML semantics for the benefit of layout (not great).
One answer to this is display: contents;—a magical new display value that essentially makes the container disappear, making the child elements children of the element the next level up in the DOM.
This value becomes useful if you want to add some element because it makes sense in terms of document semantics, but doesn’t in terms of display. Perhaps you have some content that makes sense marked up as an article, that article is then a flex item in your layout BUT the elements you really would like to be flex items are nested inside that article. Rather than flattening your markup and remove the article element to enable these inner elements to be part of the flex layout, you could remove the boxes generated by article using display: contents. You then get the best of both worlds, semantic markup plus the visual display your design requires. That sounds good to me.
display: contents makes that the div doesn’t generate any box, so its background, border and padding are not rendered. However the inherited properties like color and font have effect on the child (span element) as expected.
There is also a very related subject to all this: subgrids. Probably literally display: subgrid;. It’s probably less important in terms of maintaining semantics than display: contents; but also different.
Grid layout is the first serious candidate to fill that hole in the past two decades, and I don’t want to see them hamstrung from the outset. Subgrids are essential to the adoption of grids. I hope they’ll be implemented as soon as possible
You won’t get far through a conversation about subgrid in CSS Grid Layout without someone suggesting that display: contents solves most of the problems anyway, so do we really need subgrid? This really isn’t the case, display: contents does indeed solve a class of problems, but these are different problems to those that subgrid would help us with.
This is the third post in a four-part series. In part one, we set up a serverless Stripe function on Azure. Part two covered how we hosted the function on Github. This post will focus on wiring everything up as a Vue.js application.
Stripe has a number of ways to build out a checkout form, the most basic being a single button on the page that you trigger to pull up their custom modal. There’s a repo and component for this, but as easy as that is to implement (it’s probably the most simple way to do it), I wanted a little more customization and wanted the checkout flow to be part of the page and application. This approach wouldn’t work for my needs.
Stripe Elements
Stripe also offers a thing called Elements. Elements allow you to integrate Stripe’s payment system into your own checkout form and style it like your own site for a cohesive experience. It won’t feel like you’re using a third party plugin. They do have some pre-styled examples if you prefer something you can use right out of the box.
Luckily for us, there’s a really nice repo with a Vue version of Stripe Elements called vue-stripe-elements. The repo’s documentation is really nice, so you could check that out. Here’s how I put it to use:
npm i vue-stripe-elements-plus --save
…or using Yarn:
yarn add vue-stripe-elements-plus
Now let’s talk about our cart and integrate it.
The Cart
Here’s what everything looks like as a birds eye view of the application. We’ve already addressed the function and stripe pieces, now let’s dig into the application itself.
We’re not going to go through setting up the entire application in these posts, rather just the Cart and Checkout. I’d suggest checking out the following links before continuing if you need to catch up on the basics of Vue, Vuex, and Nuxt:
In our general store set up with Vuex, we hold a manifest of all of our product data used to populate the pages with items. We’ll also use that information to populate a (currently empty) cart object where items can be added for purchase. We’ll use that data on a page called `Cart.vue` in the pages directory. If you’re unfamiliar with Nuxt.js, it allows us to use .vue components as pages by creating them in this pages directory. We can still populate these pages with components from the components directory to create a more modular application. Here are the parts we’re discussing now:
We’ll need two pieces of information from that store in Vuex: the contents of the cart and the cartTotal.
We’ll use computed properties in pages/Cart.vue to fetch that information so that we can cache and use them in the cart.
The first thing that we’ll do is see if the cart has items in it. If it does, then we need to check that the payment hasn’t already been processed. We need to do this because there’s no need to display a checkout form if there are no items in the cart or if payment has already been processed for the items that were added.
<div v-if="cartTotal > 0">
<!--we'll add our checkout here-->
</div>
<!--If the cart is empty, give them the ability to get back to the main page to add items-->
<div v-else-if="cartTotal === 0 && success === false" class="empty">
<!--we'll add our empty state here-->
</div>
<!--If there's a success, let's let people know it's being processed, we'll add a success component later on-->
<div v-else>
<!--we'll add success here-->
</div>
We’ll also create a success property in our data that we’ll initially set to false and use later to record whether or not a payment was successfully submitted.
data() {
return {
success: false
};
},
We want to show cart items if they exist, their individual totals (as we can have multiple counts of the same item) and the final total.
<div v-if="cartTotal > 0">
<h1>Cart</h1>
<div class="cartitems"
v-for="item in cart"
key="item">
<div class="carttext">
<h4>{{ item.name }}</h4>
<p>{{ item.price | usdollar }} x {{ item.count }}</p>
<p>Total for this item: <strong>{{ item.price * item.count }}</strong></p>
</div>
<img class="cartimg" :src="`/${item.img}`" :alt="`Image of ${item.name}`">
</div>
<div class="total">
<h3>Total: {{ total | usdollar }}</h3>
</div>
<!--we're going to add our checkout here-->
</div>
We’re using a filter to format the prices in US dollars. I format them this way instead of hardcoding them in case I need to support other currencies in the future.
Now we’re going to create our checkout component, which will hold all of the Stripe checkout logic and connect to the serverless function we set up in Part Two. We’ll register the component in the Cart.vue file:
And, in the checkout component itself, we’ll bring over the base for the file that we saw in the vue-stripe-elements repo documentation:
<template>
<div id='app'>
<h1>Please give us your payment details:</h1>
<card class='stripe-card'
:class='{ complete }'
stripe='pk_test_XXXXXXXXXXXXXXXXXXXXXXXX'
:options='stripeOptions'
@change='complete = $event.complete'
/>
<button class='pay-with-stripe' @click='pay' :disabled='!complete'>Pay with credit card</button>
</div>
</template>
<script>
import { stripeKey, stripeOptions } from './stripeConfig.json'
import { Card, createToken } from 'vue-stripe-elements-plus'
export default {
data () {
return {
complete: false,
stripeOptions: {
// see https://stripe.com/docs/stripe.js#element-options for details
}
}
},
components: { Card },
methods: {
pay () {
// createToken returns a Promise which resolves in a result object with
// either a token or an error key.
// See https://stripe.com/docs/api#tokens for the token object.
// See https://stripe.com/docs/api#errors for the error object.
// More general https://stripe.com/docs/stripe.js#stripe-create-token.
createToken().then(data => console.log(data.token))
}
}
}
</script>
Next Up…
So far, this is what the component looks like out of the box. We’re going to have to update this component a bit to fit our needs, but not too much. Stay tuned tomorrow for the final installment when we connect our component to our serverless function and finish up the checkout!
In part one of this two-part article, we began building a drum sequencer in Elm. We learned the syntax, how to read and write type-annotations to ensure our functions can interact with one another, and the Elm Architecture, the pattern in which all Elm programs are designed.
In this conclusion, we’ll work through large refactors by relying on the Elm compiler, and set up recurring events that interact with JavaScript to trigger drum samples.
In 2016, 34% of the US workforce worked as freelancers, and by 2020, it’s estimated that number will rise to 43%. Freelance opportunities aren’t going anywhere, and more professionals are swapping in their office key cards for a home office.
While the idea of sitting around in sweatpants or relaxing on a beach while working sounds like perfection, freelancing isn’t always a walk in the park. From juggling business responsibilities and invoices to finding your next gig, freelancing comes with its issues. Despite these challenges, a few tips can help you find success and happiness in your career.
1. Believe in Your Worth
Particularly when you’re new to freelancing, it can be intimidating to set your fee. While some projects or jobs may entail negotiation, it’s best to set your rates and stick to them. Depending on your niche, you may work on an hourly rate or quote per project. Set a rate that’s on trend with your industry rather than settle. While you may find more gigs when charging less than the industry average, you’ll experience more stress trying to juggle enough projects to meet your income goals.
2. Network Even When You’re Not Seeking Work
Networking is the lifeblood of freelancing; it’s necessary to keep your business alive. Even when you have contracts, freelancing jobs can be unpredictable. You may have ten small projects one month and three ongoing projects another month.
Finding yourself low on projects can be stressful to your mental health and your wallet. Keep networking with other professionals, freelancers, and potential employers even with plenty of projects on your plate. This effort makes it easier to find a job when you’re looking for your next gig.
3. Hire an Accountant
If you make a single business investment, hire an accountant. Unlike W-2 employees, who have a portion of taxes paid by their employers, freelancers have to cover all of their own taxes and manage their own expenses.
During tax season, it can be confusing and overwhelming to determine the tax credits for which you qualify and what taxes you owe. Working with an accountant not only makes it easier to track expenses and save on taxes but also gives you clearer insight into how much you’re earning after taxes.
4. Set a Schedule and Stick to It
Working the standard nine-to-five Monday through Friday can feel restrictive, but businesses are onto something when they adhere to a consistent schedule. Whether you prefer to work late at night or early in the morning, set a regular schedule for your work week, including the days and hours you’ll work. Aim to schedule four days of work and one day for handling administrative tasks, such as following up on emails, taking care of bills and invoices, and networking. A regular schedule helps you get into a work mindset each time you start your day.
5. Don’t Skimp on Business Necessities
Working as a freelancer means wearing a business-owner hat too. While it’s tempting to cut back on costs wherever you can, it’s worth investing in the tools you need to do your work efficiently. One service you should never skimp on is a reliable high-speed internet connection for communicating with employers and completing projects. Take the time to find the fastest internet in your area and calculate your bandwidth needs based on the type of work you do. With a fast connection, you can complete your work faster and avoid the frustrations of lag.
6. Don’t Be Afraid to Say “No”
When you determine your income, it’s easy to make the mistake of taking on too much work. If you’re tempted to take on another project for the additional income, consider the cons: additional stress and less time to decompress. Don’t risk your mental health for a bump in pay. Before agreeing to any new project, look to see if it will realistically fit into your schedule. If it won’t, turn it down or explain what deadline would work for you.
Working as a freelancer is an exciting career move, offering independence and opportunities to challenge yourself and enhance your skills. While freelancing isn’t the easiest gig, following these helpful tips can help you find happiness and success in your career.
As a designer, you can never have too many fonts. The projects are way too diverse, and the supply is massive: this makes it easy to always use new fonts. Handwritten, more rough fonts have been the center of attention in the past months, but classic sans serif and modern, yet bold fonts are in demand as well.
While we already checked if the fonts are also free to use for commercial use, you should still always double check that yourself. When in doubt, ask the originator.
We’re now in the second post of a four-part series where we’re creating a checkout form application in Vue.js that can accept payments via the Stripe API. In part one, we looked at the concept of serverless functions, set one up in Azure, and connected it to a Stripe account. In this post, we’ll focus on setting up Stripe as a serverless function and hosting it all on Github.
First, we’re going write our function and test it out in the portal, but eventually we’re going to move it over to Github and have Azure pull in the code. I’ll explain why we do this in a moment.
For now, in order to get it working and testable, we’re going to write it in the portal and fill in the request body to perform the test. But we need to know what Stripe will expect from us first.
Dun dun dun…
Working With Stripe as a Serverless Function
If you check out Stripe’s documentation, you can see that we’ll need to grab the Stripe token in the dashboard. This will eventually mirror the POST parameters submitted by our form. Stripe makes it easy, so it’s fairly straightforward to use their library for the server-side function with Express:
We won’t need to set up all of Node and Express for this, though, as what we really need is the amount, the currency, the description, and the token, which we can integrate with the testing code we were provided earlier in the portal’s view of our function. So, let’s head over to the Azure portal where our function lives and update that default testing code to accept the parameters we need for Stripe, and also populate the request.body in the test panel.
We’ll add our Stripe testing key and kick everything off. To be totally sure, we’re going to log what we’ve gotten started:
var stripe = require('stripe')('sk_test_whateveryourtestingkeyisgoeshere');
// ^ this is a stripe testing key
module.exports = function(context, req) {
context.log('starting to get down');
If we have a request body, an email, and a token, then let’s get started. We’ll create a customer from the email and then use that customer to create the Stripe charges, passing in the amount of the charge as we do so.
We also want to test if this all completed successfully, or if it errored out. If it did error, we need to log what that error is. We’ll also see if the whole thing errored entirely, making sure we’re logging everything appropriately along the way.
You’ll note that I log a lot. I think it’s not enough to know that something has errored. I want to know when the error happened and why so that I can track it down. This makes it much easier to debug if something were to go wrong.
In the testing area on the right side of the portal, we’ll fill the request.body with the stripeEmail, stripeToken (a testing token in this case), and some random amount for the charge. When we run this, we can see that it works! We get a 200 OK Status, and we’ve logged This has been completed in the output.
Github-Hosted Serverless Function
Let’s put everything in Github now that it’s working. One big reason we want to do this is because our function will have a dependency on Stripe’s library. If you head over to the sample-stripe-handler repo I’ve created for this tutorial, you’ll see a package.json file. The most important lines in that file are these:
"dependencies": {
"stripe": "^5.3.0"
}
This tells the function to pull in the correct version of the Stripe API that we need to use in order for our app to properly function. As a note, you could also use this method to write other kinds of functions using other libraries. This means the possibilities for what to create are endless!
We’ll pull everything from our function into this repo. This includes the function itself, the package.json file, as well as the contents of the function.json file that you’ll see in the “View Files” tab on the right in the Azure portal.
Once we have that all in ready to go in a Github repo, we’ll head back over to the Azure portal, because now we have to let Azure know that we’d like to use this repo to host our function instead of our test. We can still test our function inside the portal—we just won’t be able to edit it via the GUI anymore.
Click on the “Platform Features” tab and select the “Deployment Options” item.
From here, click “Settings” then “Choose source” and a number of options will be provided. I’m going to choose Github because that’s where I want to host mine, but you can see that there are a lot of other ways we could have done this.
Once Github has been selected, you will be able to configure which repo you would like to use as your deployment source. I chose the sample-stripe-handler repo that we created earlier.
After we’ve done this and it’s loaded, you’ll be taken to a “Deployments” screen that shows the last commit that you made to the repo. That means everything’s working correctly!
Let’s test this a little further. My function didn’t work properly the first time because I was using ES6. I could have added in Babel, but I just converted it back to ES5 and pushed to the master branch. You can see the function.json becomes inactive as the last deployment, and my latest commit message—which is mostly me grumbling—is now the latest deploy! Awesome.
We can’t be too careful so, to check that these tests did indeed work, I’m going to head over to the Stripe dashboard. Sure enough, there are testing charges showing up in our dashboard ?
One last thing!
We would be remiss to exclude our good friend CORS, which we need to properly enable for everything to communicate as it should. Let’s go to our function in the dashboard, and select CORS:
In the prompt that appears, we’ll whitelist our localhost dev server, as well as our final URL for the site. Voila! We’re all set.
Next Up…
We got a lot done in this post! Next, we’ll want to learn how to move away from testing only within the function and get this sucker communicating freely with a checkout experience that we’ll build within a Vue.js application. Stay tuned!
There’s a high chance you came across the term “REST API” if you’ve thought about getting data from another source on the internet, such as Twitter or Github. But what is a REST API? What can it do for you? How do you use it?
In this article, you’ll learn everything you need to know about REST APIs to be able to read API documentations and use them effectively.
Gather ’round, ladies, gents, and children. Lo, before your very eyes, we shall reveal several freaks of the Internet! Behold! Websites that don’t need JavaScript to display their god-given content!
Oh, you think I’m kidding? Websites that are presented by plain old HTML and CSS are becoming increasingly rare. At this juncture, I don’t know who to blame, and is it really worth blaming anybody? I could point finger at whomever or whatever I think is to blame, or I could point fingers at creative and sometimes large websites that do it right!
Now, what do I mean about “doing it right”? Some of these sites, you might notice, do implement some things with JavaScript. But here’s the secret: if you turn JavaScript off, these sites still work just fine. The content doesn’t just disappear. The JavaScript effects and features have fallbacks! Sites are progressively enhanced, or they degrade gracefully.
Either way: they work. And they’re kind of hard to find, these days.
1. Amazon
You might expect a site with as much information present on any given page as Amazon has to use a mountain of JavaScript to, in some way, organize it more efficiently. Not so. Turn off the JS, and you can buy stuff just fine.
2. The Warren Trust
The Warren Trust is another one that degrades quite gracefully. With JS on, the site uses AJAX techniques to load content from other pages without technically leaving the home page. Turn off the JS, and it won’t work quite like it does with the JS on, but it does work. You can still see every page, but, you know, on its own page.
3. Stuff & Nonsense
Stuff & Nonsense was created by known and self-admitted web designer Andy Clarke. So yeah, it work with and without JS just fine. It’s a lovely example of a site that (mostly) works perfectly fine either way.
The only thing that doesn’t work when JS is turned off is the audio player. That is kind of to be expected, really. I can’t take many points away for that.
4. Mike Mai
Mike Mai’s site is proof enough that your site can be plenty creative—if a little odd in this case—with or without scripting. And I do mean “odd”, and I really do mean “little”.
It may not be the poster-site for visual accessibility, but it does show what kind of things can be accomplished in plain old HTML and CSS by those just crazy enough to try it.
5. Solace House
Solace House is a sobering example of a site that absolutely needs to work any time, under any circumstance, no matter which technologies are or aren’t working. It’s a suicide prevention center, after all.
You might be able to argue that your target demographic should just have JavaScript enabled at all times in some circumstances, but there are some services that are just too vital to ever leave to chance.
6. Twitter
Yeah, thatTwitter. It was while researching this article that I found out Twitter works well enough without JavaScript. Well, their solution is a bit convoluted, perhaps, but it’s effective.
In short, Twitter will actually redirect you to a pared-down, mobile version of Twitter. It’s fully functional, except for features like feeds that update live, and so on. Who says social media needs JavaScript?
Truth be told, Twitter never felt faster.
7. Slack
You might need JavaScript to actually run a Slack chatroom, but the rest of the client-facing site looks and works just fine. It even has a condition in the URL for no JavaScript. And when you need to enable JS to make things run, they tell you! They actually tell you!
No seriously, it’s a thing that lots of sites would rather let you stare at a blank page than even say, “Woops! Looks like the JS broke, or you need to enable it.” I dislike this thing.
8. WebdesignerDepot
No, seriously, try it out. You’ll see a few visual downgrades, but everything essential looks fine, and works well. This is what it’s all about, people!
I’d love to take some credit for that, but I just write here on occasion. I guess this is my official letter of congratulations to the designer!
In Conclusion
I just wanted to show people what could be done. That’s it. I’m not saying you should ditch JS entirely, but I do believe that we should be a lot more considered about what we do and don’t implement in JavaScript.
Look at the sites I’ve listed here. Look at your own. For every thing you implement with a script, ask yourself if you really, really need to make it a script. For that matter, do you really need HTML?
(This is a sponsored article.) Before embarking upon the design phase of any project, it’s critical to undertake some research so that the decisions you make are undertaken from an informed position. In this third article of my series for Adobe XD, I’ll be focusing on the importance of undertaking user research.
Your job title might not be “design researcher”, but that doesn’t mean you shouldn’t at the very least inform yourself of your users and their needs by undertaking at least some initial scoping research before you embark upon a project.