Craft.do Custom Domain
Currently Craft's sharing pages do not support custom domains, so I wrote a Cloudflare Worker script to reverse proxy Craft pages to achieve the effect of custom domains.
Demo
Source Code
Video Tutorial
Done
- The site can be configured in the Craft editor
- Page content updated in real time
- Complete adaptation of Craft pages
- Support page whitelist
- Password access support (public but requires password access)
- Support for Craft comments
- Support for comment notifications (notifications sent to Telegram)
- Support for customizing the site UI in the Craft editor
- Optimize image cache
- Support sitemap
- SEO Optimization
In Development
- RSS support
- Search Support
- Support for external pages
How to use
1. Preparation
You need to prepare the below account and domain name:
- Cloudflare account
- Hosted domain name in Cloudflare
- Craft Docs account
- Telegram account (optional, for receiving comment notifications)
These services are free, including Cloudflare Worker daily have 100,000 free quota (personal website is completely enough), Craft Docs free account can also use this script.
2. Setting up DNS resolution
Open the Cloudflare dashboard, and add a CNAME record to the domain name settings. If you have a domain name
mydomain.com
, and you want to use mydomain.com
directly as a Craft site, put @
in the "Name" field, and if you want to use note.mydomain.com
as a Craft site, put note
in the "Name" field.The "Target" field is
craft.do
, in fact, any other valid domain name is fine here, but let's be safe and write the Craft domain name.3. Initialize the site
First create a folder in the Craft software, such as
My Public Notes
or any other name you like. In the folder, create a new page that will be used as the home page of your site, and you can layout this page whatever you like.Click share this page and turn off "show title" so that your home page will look better.
Copy the share link of this page, we need it immediately.
Now we need to create one more page, which will be used as the configuration center for the whole site. Now we open this "configuration" page, and on the first line of this page (make sure it's the first line) we insert a block of code, as shown below:
Craft will pop up a code entry box, highlight JSON and select it.
Fill in the box below:
{ "index": "https://www.craft.do/s/XXXXXXXXX" }
The
index
is immutable, and the following link is the copied from the "Home" page share link.As a final step, open this "configuration" page to share too, and copy the share link. Now your Craft has finished initializing.
You can refer to my website, my home page is https://note.zuolan.me/ , my configuration page is here https://www.craft.do/s/3MtGzyRv7l26kF .
Later, when you have a new page you want to publish, just go to the "configuration" page and add it to the code block. For example, if I want to add an "about me" page, I just need to add the path and the Craft share link in the "configuration" page.
{ "index": "https://www.craft.do/s/XXXXXXXXX", "about": "https://www.craft.do/s/WWWWWWWWW" }
4. Deploying Worker script
Open the Cloudflare console, click on the Worker panel, and create a new worker.
You need to change three places in the new page:
- Change the name of the worker, in the following figure 1, to the name you like.
- Delete all the content in the code editor, paste the code from Github, and change the content at the top of the code according to the comments, and change it to your information.
- Click "Save and Deploy".
Go back to the Worker panel, set a route for the script you just created, select the worker you just created, fill in your domain name in the route field, and note that the
*
symbol after the route is essential.Now the script is ready.
Now you can access the home page from the domain you configured.
5. Customize your pages (Optional)
With Cloudflare Worker we can also customize some content, such as the logo menu in the top right corner of my website. If you want to customize some content, you can find two classes at the end of the script code: BodyRewriter and HeadRewriter.
Write your HTML/CSS/JS code in both classes to implement your custom page.
Here is the code for my custom menu (Click to expand).
class BodyRewriter { element(element) { element.append(` <div class="navigation"> <input type="checkbox" class="navigation__checkbox" id="nav-toggle" /> <label for="nav-toggle" class="navigation__button"> <a aria-label="toggle navigation menu"> <img alt="logo" class="navigation__logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDBwdCIgaGVpZ2h0PSIxMDBwdCIgdmlld0JveD0iMCAwIDEwMCAxMDAiPjxnIGZpbGw9ImJsdWUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDAwMDAwLDEwMCkgc2NhbGUoMC4wODAwMDAsLTAuMDgwMDAwKSI+PHBhdGggZD0iTTc2MiAxMjAzIGMtNiAtMTUgLTEzIC00NiAtMTcgLTY4IC00IC0yMiAtMTMgLTQ5IC0yMCAtNjEgLTE1IC0yMyAtMTIyIC02OSAtMjU3IC0xMDkgLTQ5IC0xNCAtODggLTI4IC04OCAtMjkgMCAtMiAzMyAtMjAgNzMgLTQwIDQ5IC0yNCA4NyAtMzYgMTE1IC0zNiAyOCAwIDQyIC00IDQyIC0xMyAwIC0zNCAtMjk1IC01MTcgLTM5MCAtNjM5IC00MCAtNTIgLTQgLTI4IDg2IDU2IDQ5IDQ2IDEwNSAxMDkgMTI0IDE0MSAxOSAzMSA2NCA5OCAxMDAgMTQ4IDc3IDEwOCAxMjUgMTg2IDE3MyAyODMgMjAgMzkgNDYgNzggNTkgODYgMTMgOCA2OSAzNCAxMjYgNTggMTA3IDQ1IDExOCA1NyAxMTAgMTExIC0zIDIxIC0xMCAyNSAtNzggMzQgbC03NSAxMCAtNSA0NSBjLTUgNDIgLTcgNDUgLTM2IDQ4IC0yNiAzIC0zMyAtMSAtNDIgLTI1eiIvPjxwYXRoIGQ9Ik03NTQgNjE2IGMtNDAgLTE5IC04OCAtMzkgLTEwOCAtNDYgLTQzIC0xNCAtNDUgLTMwIC03IC03MiAyNSAtMjggMzMgLTMxIDgwIC0zMCAzOSAxIDU0IC0zIDU4IC0xNSA3IC0xOCAtMzAgLTE0MCAtNTggLTE5MiAtMzYgLTY3IDYgLTkzIDEzNSAtODQgbDg2IDYgMCAtMjYgYzAgLTE0IC00IC0zNyAtMTAgLTUxIC01IC0xNCAtOCAtMjYgLTYgLTI2IDcgMCAxMTAgNjggMTI5IDg1IDExIDEwIDE3IDMwIDE3IDYwIDAgNjIgLTIyIDcwIC0xNTAgNTcgLTUyIC01IC05OCAtNiAtMTAzIC0yIC00IDMgMyAzMSAxNiA2MSAxMyAzMCAzMiA3OCA0MiAxMDggMTAgMzAgMjggNzAgNDEgODkgMjYgMzggMzAgNjMgMTQgOTMgLTE3IDMxIC05MSAyNSAtMTc2IC0xNXoiLz48L2c+PC9zdmc+" /> </a> </label> <div class="navigation__background"></div> <h1 class="navigation__title">左蓝的笔记</h1> <div class="navigation__icon"> <a target="_blank" href="<https://t.me/zuolan>"> <img alt="Telegram" src="data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+VGVsZWdyYW08L3RpdGxlPjxwYXRoIGZpbGw9ImdyYXkiIGQ9Ik0xMS45NDQgMEExMiAxMiAwIDAgMCAwIDEyYTEyIDEyIDAgMCAwIDEyIDEyIDEyIDEyIDAgMCAwIDEyLTEyQTEyIDEyIDAgMCAwIDEyIDBhMTIgMTIgMCAwIDAtLjA1NiAwem00Ljk2MiA3LjIyNGMuMS0uMDAyLjMyMS4wMjMuNDY1LjE0YS41MDYuNTA2IDAgMCAxIC4xNzEuMzI1Yy4wMTYuMDkzLjAzNi4zMDYuMDIuNDcyLS4xOCAxLjg5OC0uOTYyIDYuNTAyLTEuMzYgOC42MjctLjE2OC45LS40OTkgMS4yMDEtLjgyIDEuMjMtLjY5Ni4wNjUtMS4yMjUtLjQ2LTEuOS0uOTAyLTEuMDU2LS42OTMtMS42NTMtMS4xMjQtMi42NzgtMS44LTEuMTg1LS43OC0uNDE3LTEuMjEuMjU4LTEuOTEuMTc3LS4xODQgMy4yNDctMi45NzcgMy4zMDctMy4yMy4wMDctLjAzMi4wMTQtLjE1LS4wNTYtLjIxMnMtLjE3NC0uMDQxLS4yNDktLjAyNGMtLjEwNi4wMjQtMS43OTMgMS4xNC01LjA2MSAzLjM0NS0uNDguMzMtLjkxMy40OS0xLjMwMi40OC0uNDI4LS4wMDgtMS4yNTItLjI0MS0xLjg2NS0uNDQtLjc1Mi0uMjQ1LTEuMzQ5LS4zNzQtMS4yOTctLjc4OS4wMjctLjIxNi4zMjUtLjQzNy44OTMtLjY2MyAzLjQ5OC0xLjUyNCA1LjgzLTIuNTI5IDYuOTk4LTMuMDE0IDMuMzMyLTEuMzg2IDQuMDI1LTEuNjI3IDQuNDc2LTEuNjM1eiIvPjwvc3ZnPg==" /> </a> <a target="_blank" href="<https://twitter.com/izuolan>"> <img alt="Twitter" src="data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+VHdpdHRlcjwvdGl0bGU+PHBhdGggZmlsbD0iZ3JheSIgZD0iTTIzLjk1MyA0LjU3YTEwIDEwIDAgMDEtMi44MjUuNzc1IDQuOTU4IDQuOTU4IDAgMDAyLjE2My0yLjcyM2MtLjk1MS41NTUtMi4wMDUuOTU5LTMuMTI3IDEuMTg0YTQuOTIgNC45MiAwIDAwLTguMzg0IDQuNDgyQzcuNjkgOC4wOTUgNC4wNjcgNi4xMyAxLjY0IDMuMTYyYTQuODIyIDQuODIyIDAgMDAtLjY2NiAyLjQ3NWMwIDEuNzEuODcgMy4yMTMgMi4xODggNC4wOTZhNC45MDQgNC45MDQgMCAwMS0yLjIyOC0uNjE2di4wNmE0LjkyMyA0LjkyMyAwIDAwMy45NDYgNC44MjcgNC45OTYgNC45OTYgMCAwMS0yLjIxMi4wODUgNC45MzYgNC45MzYgMCAwMDQuNjA0IDMuNDE3IDkuODY3IDkuODY3IDAgMDEtNi4xMDIgMi4xMDVjLS4zOSAwLS43NzktLjAyMy0xLjE3LS4wNjdhMTMuOTk1IDEzLjk5NSAwIDAwNy41NTcgMi4yMDljOS4wNTMgMCAxMy45OTgtNy40OTYgMTMuOTk4LTEzLjk4NSAwLS4yMSAwLS40Mi0uMDE1LS42M0E5LjkzNSA5LjkzNSAwIDAwMjQgNC41OXoiLz48L3N2Zz4=" /> </a> <a target="_blank" href="<https://github.com/izuolan>"> <img alt="Giithub" src="data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+R2l0SHViPC90aXRsZT48cGF0aCBmaWxsPSJncmF5IiBkPSJNMTIgLjI5N2MtNi42MyAwLTEyIDUuMzczLTEyIDEyIDAgNS4zMDMgMy40MzggOS44IDguMjA1IDExLjM4NS42LjExMy44Mi0uMjU4LjgyLS41NzcgMC0uMjg1LS4wMS0xLjA0LS4wMTUtMi4wNC0zLjMzOC43MjQtNC4wNDItMS42MS00LjA0Mi0xLjYxQzQuNDIyIDE4LjA3IDMuNjMzIDE3LjcgMy42MzMgMTcuN2MtMS4wODctLjc0NC4wODQtLjcyOS4wODQtLjcyOSAxLjIwNS4wODQgMS44MzggMS4yMzYgMS44MzggMS4yMzYgMS4wNyAxLjgzNSAyLjgwOSAxLjMwNSAzLjQ5NS45OTguMTA4LS43NzYuNDE3LTEuMzA1Ljc2LTEuNjA1LTIuNjY1LS4zLTUuNDY2LTEuMzMyLTUuNDY2LTUuOTMgMC0xLjMxLjQ2NS0yLjM4IDEuMjM1LTMuMjItLjEzNS0uMzAzLS41NC0xLjUyMy4xMDUtMy4xNzYgMCAwIDEuMDA1LS4zMjIgMy4zIDEuMjMuOTYtLjI2NyAxLjk4LS4zOTkgMy0uNDA1IDEuMDIuMDA2IDIuMDQuMTM4IDMgLjQwNSAyLjI4LTEuNTUyIDMuMjg1LTEuMjMgMy4yODUtMS4yMy42NDUgMS42NTMuMjQgMi44NzMuMTIgMy4xNzYuNzY1Ljg0IDEuMjMgMS45MSAxLjIzIDMuMjIgMCA0LjYxLTIuODA1IDUuNjI1LTUuNDc1IDUuOTIuNDIuMzYuODEgMS4wOTYuODEgMi4yMiAwIDEuNjA2LS4wMTUgMi44OTYtLjAxNSAzLjI4NiAwIC4zMTUuMjEuNjkuODI1LjU3QzIwLjU2NSAyMi4wOTIgMjQgMTcuNTkyIDI0IDEyLjI5N2MwLTYuNjI3LTUuMzczLTEyLTEyLTEyIi8+PC9zdmc+" /> </a> </div> <nav class="navigation__nav" role="navigation"> <ul class="navigation__list"> <li class="navigation__item"> <a href="<https://note.zuolan.me/>" target="_blank" class="navigation__link">首页</a> </li> <li class="navigation__item"> <a href="<https://note.zuolan.me/about>" target="_blank" class="navigation__link">关于</a> </li> <li class="navigation__item"> <a href="#" class="navigation__link">联系</a> </li> </ul> <p class="footer">© CC BY-NC-SA 4.0</p> </nav> </div> `, { html: true }) } } class HeadRewriter { element(element) { element.append(` <style> /* Hide the Craft "Login in" button in comment board. */ .sc-CtfFt { visibility: hidden; } .hGGlzy { visibility: hidden; } .header .right-side { padding-right: 3rem; } .navigation { position: fixed; top: 0; right: 0; z-index: 400; } .navigation__checkbox { display: none; } .navigation__button { position: absolute; top: 0.5rem; right: 0.8rem; height: 2.4rem; width: 2.4rem; text-align: center; border-radius: 50%; z-index: 300; cursor: pointer; } .navigation__logo { width: 1.5rem; height: 1.5rem; padding-top: 0.4rem; padding-right: 0.1rem; } .navigation__title { position: fixed; top: 0.5rem; right: 3rem; visibility: hidden; margin: 0.5rem 1rem; color: gray; font-size: 1rem; z-index: 300; transition: all 200ms ease-out; } .navigation__background { position: fixed; top: 0.5rem; right: 0.7rem; height: 2.4rem; width: 2.4rem; border-radius: 50%; background: #FFFFFF; /* background-size: cover; background-position: center; */ z-index: 100; transition: all 400ms cubic-bezier(0.86, 0, 0.07, 1); } .navigation__nav { position: fixed; top: 0; right: 0; opacity: 0; width: 100%; visibility: hidden; z-index: 200; transition: all 400ms ease-in; } .navigation__icon { position: fixed; top: 17rem; right: 0; visibility: hidden; margin: 0.8rem 2rem; z-index: 300; transition: all 200ms ease-out; } .navigation__icon a { top: 0; right: 0; display: inline-block; width: 1rem; margin: 0.5rem; z-index: 300; } .navigation__list { position: absolute; top: 4rem; right: 1rem; list-style: none; } .navigation__item { margin: 1rem; } .navigation__link:link, .navigation__link:visited { display: inline-block; padding: 0.5rem 1rem; color: #494b4e; font-size: 1.4rem; text-decoration: none; transition: all 0.2s; } .navigation__icon a:hover { opacity: 0.7; } .navigation__link:hover { color: #494b4e; transform: scale(1.2); } .navigation__checkbox:checked ~ .navigation__background { background: #edeeee; transform: scale(20); /* transform: scale(80); */ } .navigation__checkbox:checked ~ .navigation__title { visibility: visible; opacity: 1; } .navigation__checkbox:checked ~ .navigation__icon { visibility: visible; opacity: 1; } .navigation__checkbox:checked ~ .navigation__nav { width: 100%; visibility: visible; opacity: 1; } .footer { position: absolute; top: 20rem; right: 2rem; color: #b7c0c3; font-size: 0.8rem; } </style> `, { html: true }) } }