This tutorial will demonstrate a workflow for creating a landing page (with email signup form) for a new project. Part of The Solo Hacker's Guide To Clojure. Prerequisites: First Steps With Clojure.
Demo
Clone the Mystery Cows
repository and checkout the landing-page
branch. Run ./task setup
to
install a couple npm deps and download the Bootstrap source (if you don't have
npm installed, do that first). Then run ./task dev live
to start a
development server.
(I'm going to assume your environment has the ability to run shell scripts. I figure this is a reasonable assumption since Windows 10 has the Windows Subsystem for Linux. But if you can't run shell scripts, you can just look inside the files and run the individual commands yourself. I won't be doing much shell scripting anyway.)
A landing page (like this one) should open in
your web browser. Whenever a Clojure file changes on disk, the task we ran
will regenerate the public/index.html
file and reload the page in your web
browser. Try it out: open src/cows/core.clj
and change the nav bar so it says
"Mystery Sows" instead of "Mystery Cows" (which is a real
thing
in case you're wondering).
(By the way, the email form will give you console errors if you try to use it because it has a Firebase dependency which we haven't set up yet. More on that later.)
The code
This file uses Rum server-side rendering to generate the html. Things you may not have seen yet:
(for ...)
Always worth a look.
Note that clj -m cows.core
calls the -main
function from src/cows/core.clj
.
This is where you can customize Bootstrap's CSS.
Do it yourself
Now, create a separate project for your own landing page:
Set up a skeleton for the project. Copy over deps.edn
, task
and
bootstrap/custom.scss
, then add a bare-bones src/yourproject/core.clj
file with just a "hello world" div. Also include a head section with the
title and meta elements. Run ./task setup
, then start the dev server and
make sure it works.
Generate a favicon (favicon.io). Place the generated
files in public/
and link to them from yourproject.core
.
Add links to Bootstrap from yourproject.core
. Change the theme colors in
bootstrap/custom.scss
(unless you want to leave it as "cowpie brown").
You can use use coolers.co or something similar
to help you pick some colors.
Write the HTML/CSS in cows.core
. You could do it from scratch without too
much effort, but I searched for "free bootstrap themes" and ended up on
this one. If you take
that route, use this site to convert
the HTML to Clojure data structures. Wrap the output in a (defc landing-page [] ...)
as in cows.core
. You'll have to do a little
editing.
For one thing, Rum is slightly different from
Hiccup. Hiccup uses only strings
for inline CSS, so you can't write something like [:p {:style {:background-color "green"}} ...]
. Instead, you'd have to write [:p {:style "background-color: green;"}]
. Rum is the opposite way, so if you
get any compilation errors, you may need to convert the strings to maps by
hand.
Also stick any images and CSS files from the theme you copied somewhere
under public/
, adding the appropriate links to the head section. I'd
recommend rewriting the CSS into yourproject.core
in most cases, but some
things (like media queries) can't be written inline, so feel free to leave
those in a separate CSS file. (See
Garden if you want a 100% Clojure
solution.)
Finally, you can break up the HTML structures into separate variables and
components like I've done in cows.core
. For example, the "testimonial
items" were originally three separate blocks of HTML, but I consolidated
them into a component and a for
.
For stock photos, I recommend pexels.com (that's where I got all the cows).
Once your landing page is looking good, the next step is to make the signup form actually work. We'll need to set up Firebase as we'll be using that for storing the email addresses (and for hosting).
Go to firebase.google.com and set up a new project.
From that website, create a Firestore database. After it's provisioned,
click "Start collection" and set the ID to signups
. Add a single string
field called email
.
Follow this guide to install the
Firebase CLI. Once you get past the firebase login
part, run firebase init firestore
.
Replace the the new firestore.rules
file with the one from Mystery Cows.
Those rules will let your signup form add new email addresses, and it will
prevent users from reading or modifying the saved addresses. Run firebase deploy --only firestore:rules
.
In cows.core
, you'll notice three Firebase :script
elements. Add those
elements to yourproject.core
.
The :src
values are special "Hosting URLs" that Firebase can use to add
the dependencies for you along with project-specific configuration. See
here.
Run ./task dev
(not ./task dev live
). This will serve your app using
the Firebase dev server instead of the npm live server. This is necessary
so that the Hosting URLs will work. Unfortunately, you'll have to manually
refresh the page whenever you regenerate the index.html
file.
Now all that's left is to hook up some JS to your signup form and then deploy
the landing page. See public/js/main.js
and the signup form elements in
cows.core
to see how I did the former. Once you set that up, test out the
signup form. You can check the Firebase console to make sure that the email was
saved.
Finally, run firebase init hosting
and then firebase deploy
. Your landing
page should be live. You can hook up a custom domain now if you want, or just
use one of the provided domains. Later, when you set up a mailing list, you can
import the emails you get from Firebase. (I use Mailgun with some custom code
myself, but Firebase somewhat recently made a convenient extension for adding
new users to Mailchimp, so that could be a decent option. We'll go more into
that eventually.)
Next, add authentication.