Builder Book is an open source web app to publish documentation or books. The app is built with React/Material-UI/Next/Express/Mongoose/MongoDB and includes these third party APIs: Google, Github, AWS SES, Mailchimp, Stripe.
- Live app: https://builderbook.org/books/builder-book/introduction.
- Learn how to build this app from scratch with our book
- As learning material for React/Material-UI/Next/Express/Mongoose/MongoDB stack and Google/Github/AWS SES/Mailchimp/Stripe APIs.
You can start from our boilerplate or modify the final app into your own project.
For initial load, pages are rendered by the server; for subsequent loads, pages are rendered on the client. - As a production-ready web app to publish documentation or sell books on your own website.
-
Clone the project and run
yarn
to add packages. -
Before you start the app, create a
.env
file at the app's root. This file must have values for env variables specified below.-
To get
MONGO_URL_TEST
, we recommend a free MongoDB at mLab. -
Get
Google_clientID
andGoogle_clientSecret
by following official OAuth tutorial.Important: For Google OAuth app, callback URL is: http://localhost:8000/oauth2callback
Important: You have to enable Google+ API in your Google Cloud Platform account.
-
Specify your own secret key for Express session
SESSION_SECRET
: https://github.com/expressjs/session#secret
To use all features and third-party integrations (such as Stripe, Google OAuth, Mailchimp), add values to all env variables in
.env
file:.env
:MONGO_URL="XXXXXX" MONGO_URL_TEST="XXXXXX" Google_clientID="XXXXXX" Google_clientSecret="XXXXXX" SESSION_SECRET="XXXXXX" Amazon_accessKeyId="XXXXXX" Amazon_secretAccessKey="XXXXXX" EMAIL_SUPPORT_FROM_ADDRESS="XXXXXX" Github_Test_ClientID="XXXXXX" Github_Test_SecretKey="XXXXXX" Github_Live_ClientID="XXXXXX" Github_Live_SecretKey="XXXXXX" Stripe_Test_SecretKey="XXXXXX" Stripe_Live_SecretKey="XXXXXX" Stripe_Test_PublishableKey="XXXXXX" Stripe_Live_PublishableKey="XXXXXX" MAILCHIMP_API_KEY="XXXXXX" MAILCHIMP_REGION="XXXXXX" MAILCHIMP_PREORDERED_LIST_ID="XXXXXX" MAILCHIMP_ORDERED_LIST_ID="XXXXXX"
-
-
Start the app with
yarn dev
. -
The first registered user in the app becomes an Admin user (
"isAdmin": true
).
-
Create a new Github repo (public or private).
-
In that repo, create an
introduction.md
file and write some content. -
At the top of your
introduction.md
file, add metadata in the format shown below. See this file as an example.--- title: Introduction seoTitle: title for search engines seoDescription: description for search engines isFree: true ---
-
Go to the app, click "Connect Github".
-
Click "Add Book". Enter details and select the Github repo you created.
-
Click "Save".
When you add new .md
files or update content, go to the BookDetail
page of your app and click Sync with Github
.
IMPORTANT: All .md
files in your Github repo must have metadata in the format shown above.
IMPORTANT: All .md
files in your Github repo must have name introduction.md
or chapter-N.md
.
To make the content of a .md
file private (meaning a person must purchase the content to see it), remove isFree:true
and add excerpt:""
. Add some excerpt content - this content is public and serves as a free preview.
- Install now:
npm install -g now
. - Point your domain to Zeit world nameservers: three steps.
- Check the
now.json
file. If you are usingdotenv
and.env
for env variables, no need to changenow.json
. If you make changes to the app, check up how to configure now. - Make sure you updated
ROOT_URL
inpackage.json
andlib/getRootURL.js
. - Check that you have all production-level env variables in
.env
. - In your terminal, deploy the app by running
now
. - Now outputs your deployment's URL, for example:
builderbook-zomcvzgtvc.now.sh
. - Point successful deployment to your domain, for example:
now ln builderbook-zomcvzgtvc.now.sh builderbook.org
.
Chapter excerpt with Buy Button for Pubilc/Guest visitor:
Chapter content and Table of Contents for book Customer:
Add-book/Edit-book page for Admin user:
Book-detail page for Admin user:
- Google OAuth
- Github
- AWS SES
- Stripe
- MailChimp
Check out package.json.
.
├── boilerplate # Boilerplate with React, Material-UI, Next, Express, Mongoose, MongoDB
├── book # Codebases for each chapter of our book
├── components # React components
│ ├── admin # Components used on Admin pages
│ │ ├── EditBook.js # Edit title, price, and repo of book
│ │ ├── GiveFreeBook.js # Give free book to user
│ ├── customer # Components used on Customer pages
│ │ ├── Bookmark.js # Bookmark a section within a book chapter
│ │ ├── BuyButton.js # Buy book
│ ├── BookReviews.js # Component that outputs grid of reviews
│ ├── Header.js # Header component
│ ├── HomeFooter.js # Footer component on homepage
│ ├── HomeHeader.js # Header component on homepage
│ ├── MenuDrop.js # Dropdown menu
│ ├── Notifier.js # In-app notifications for app's users
│ ├── SharedStyles.js # List of _reusable_ styles
│ ├── TOC.js # Table of Contents
├── lib # Code available on both client and server
│ ├── api # Client-side API methods
│ │ ├── admin.js # Admin user methods
│ │ ├── customer.js # Customer user methods
│ │ ├── getRootURL.js # Returns ROOT_URL
│ │ ├── public.js # Public user methods
│ │ ├── sendRequest.js # Reusable code for all GET and POST requests
│ ├── context.js # Context for Material-UI integration
│ ├── notifier.js # Contains notify() function that loads Notifier component
│ ├── withAuth.js # HOC that passes user to pages and more
│ ├── withLayout.js # HOC for SSR with Material-UI and more
├── pages # Pages
│ ├── admin # Admin pages
│ │ ├── add-book.js # Page to add a new book
│ │ ├── book-detail.js # Page to view book details and sync content with Github
│ │ ├── edit-book.js # Page to update title, price, and repo of book
│ │ ├── index.js # Main Admin page that has all books and more
│ ├── customer # Customer pages
│ │ ├── my-books.js # Customer's dashboard
│ ├── public # Public pages (accessible to logged out users)
│ │ ├── login.js # Login page
│ │ ├── read-chapter.js # Page with chapter's content
│ ├── _document.js # Allows to customize pages (feature of Next.js)
│ ├── index.js # Homepage
│ ├── book.js # Book page
├── server # Server code
│ ├── api # Express routes, route-level middleware
│ │ ├── admin.js # Admin routes
│ │ ├── customer.js # Customer routes
│ │ ├── index.js # Mounts all Express routes on server
│ │ ├── public.js # Public routes
│ ├── models # Mongoose models
│ │ ├── Book.js # Book model
│ │ ├── Chapter.js # Chapter model
│ │ ├── EmailTemplate.js # Email Template model
│ │ ├── Purchase.js # Purchase model
│ │ ├── User.js # User model
│ ├── utils # Server-side util
│ │ ├──slugify.js # Generates slug for any Model
│ ├── app.js # Custom Express/Next server
│ ├── aws.js # AWS SES API
│ ├── github.js # Github API
│ ├── google.js # Google OAuth API
│ ├── logs.js # Logger
│ ├── mailchimp.js # MailChimp API
│ ├── routesWithSlug.js # Express routes that contain slug
│ ├── sitemapAndRobots.js # Express routes for sitemap.xml and robots.txt
│ ├── stripe.js # Stripe API
├── static # Static resources
│ ├── robots.txt # Rules for search engine bots
├── test/server/utils # Tests
│ ├── slugify.test.js # Unit test for generateSlug() function
├── .babelrc # Config for Babel
├── .eslintrc.js # Config for Eslint
├── .gitignore # List of ignored files and directories
├── .npmignore # Files and directories that are not uploaded to the server
├── now.json # Settings for now from Zeit
├── package.json # List of packages and scripts
├── yarn.lock # Exact versions of packages. Generated by yarn.
We welcome suggestions and pull requests, especially for issues labeled as discussion
and contributions welcome
.
By participating in this project, you are expected to uphold Builder Book's Code of Conduct.
All code in this repository is provided under the MIT License.