Edge, an OpenSource NextJS application with dynamic API for makers and developers.
Tags: javascript, react, nextjs, webmonetization
Published: 2020-05-31 08:08:04

During the last months, we have been working on an OpenSource tool called Edge. 

 - Repo [here](https://github.com/nucleo-org/edge-next)
 - [Landing site](https://edge.nucleo.is/)
 - [Demo page built with Edge](http://edge-next.now.sh/)


Edge offers a full-fledged Nextjs server capable of being deployed in minutes, adapting to your needs, only by changing some configuration options. It offers **Dynamic API, dynamic dashboard, basic authentication, and authorization based in Roles, file upload, emails**, and much more, **all implemented**.

Edge can be the foundation for your next MVP or web prototype. 


## Why Edge?

Edge serves the purpose of being able to prototype a new idea easily. 

Some examples: 

- You need to launch a platform for a client with a small budget. And several "boring" things like user authentication, basic API endpoints, static pages, could be resolved for you. Later you can extend edge to adjust to your needs or use it as a stand-alone API. 

- You want to launch a social platform where users can post content: Recipes, Advertisements, Book Reviews, you name it. It is easy with Edge, for your first version. Later on, you maybe need some custom development to adapt it to your needs. 

- You want to launch your own blog, but you don't want to deploy another instance for your CMS. You have a built in dashboard in Edge.

- You need an content type based API and a landing page for your product in a quick time

## What are the features of Edge?

### Content
- Dynamic forms based on content-type definitions. Allowing users to create any kind of content. Just define them on a config file
- Dynamic API with roles, based on content-type definitions. Easily configure your API to support all the content types your project needs. 
- Dynamic content-views to list all the content and be SEO friendly (with the content slug for the URL, and server-side rendering)
- Content can be categorized by tags.
- Web monetization built in for content


### Users
- Possibility to define new user roles or use the standard (ADMIN, USER, PUBLIC). 
- Administration dashboard to block or unblock users. 
- Login and register with social providers. Edge offers integration with Github, Google, and Facebook.  It uses passport so it is easy to add many more.
- Cool user profiles

### Files
- Content can contain files. Edge has integrated code to work with Google Cloud Platform but is easily extendable to different storage providers

### Comments

- Content can have comments. Comments are role-based and can create a conversation between users.

### Administration
- The administration role can access to some dashboards to control content and users.

![Dashboard](https://dev-to-uploads.s3.amazonaws.com/i/k7psg55g22yg8oqnklmx.png)

### Themes

Built-in CSS themes **Light, Dark, Robot, Edge, Kawaii**. Allowing users to change their theme preference.

![Themes](https://dev-to-uploads.s3.amazonaws.com/i/6shycy411wpqzoivsv06.png)

### React Components

We coded **many components** that you can find here: https://edge-next.now.sh/components. 

![Components](https://dev-to-uploads.s3.amazonaws.com/i/p3ixqo3qrqi98m6dwur8.png)

**Why we didn't use MaterialUI or another component library?** We want full control of our developments. We want something we can touch, delete, break, adapt.


### Other Features
- PWA provided by [next-pwa](https://github.com/shadowwalker/next-pwa)
- Markdown static page rendering. Static content generation with markdown support
- Markdown dynamic content. Support for markdown in content-types


## How do I use Edge, now?

It is really easy, just clone our [repository](https://github.com/nucleo-org/edge-next) and follow the setup instructions.

Setup instructions:
- run `yarn`
- run `yarn dev` to start working

You will need to configure the different environment variables (take a look at the [documentation](https://github.com/nucleo-org/edge-next/blob/master/DOCUMENTATION.md) ) for configuring all the features (Mongo, storage, social login, etc). But once you create all the keys you need, you will have your site up and running. **That's how we deployed [Edgechain](https://edgechain.xyz) just in a couple of hours of work!** 




## Some Documentation

### Creating new content types

To create a new content type you will need to edit the `edge.config.js` file and add as many content type definitions as you want.

````javascript
const contentType = {
  // The name for this content type
  title: 'Blog Posts',

  // The URL for the API and client routes
  slug: 'blog-posts',

  // How slugs are going to be generated for new content. 
  // For example "a-new-blog-post-123132132"
  slugGeneration: ['title', 'createdAt'],

  // Sets of permissions for the API and client sides
  permissions: {
    // Who can read the content
    read: ['PUBLIC'],

    // Who can create content
    create: ['ADMIN', 'USER'],

    // Who can edit ANY content
    update: ['ADMIN'],

    // Who can delete ANY content
    delete: ['ADMIN'],

    // Who can perform all of the above
    admin: ['ADMIN']
  },

  // Publishing and SEO settings
  publishing: {

    // Allow content owners to mark the content as draft and avoid visibility
    draftMode: true,

    // Which field will be used for SEO and linking
    title: 'title'
  },

  monetization: {
    web: true // Enable web monetization for a content type
  },

  
  // A list of fields, see Edge next documentation for more information
  fields: [{
    // Required values
    name: 'title',
    type: 'text',
    label: 'Post title',

    // Optional values
    placeholder: 'Type your title',
    minlength: 10,
    maxlength: 200,
    required: true,
  }]
}
````

### Enabling or disabling comments on content types

Comments are disabled by default. If you want to enable them on a content type just add 
````javascript
const postContentType = {
  /* ... previous configuration ... */
  comments: {
    enabled: true
  }
}
```

Then you can fine-tune the permissions: 
````javascript
const postContentType = {
  /* ... previous configuration ... */
  comments: {
    enabled: true,
    permissions: {
      read: ['PUBLIC'],
      create: ['ADMIN', 'USER'],
      update: ['ADMIN'],
      delete: ['ADMIN'],
      admin: ['ADMIN'],
    },
  }
}
```
Permissions like `update` and `delete` imply that the user will be able to edit ANY or delete ANY comment. Any logged user is able to edit or delete it's own comments or comment.

----

## Configuring environment variables


For that, create a file called `.env.local` and add the following code:

```
BASE_URL=http://localhost:3000
MONGODB_URI=MONGODB_URI=mongodb+srv://<username>:<password>@<url>
MONGODB_DATABASE=<database>
SENDGRID_KEY=XXX
FACEBOOK_ID=XX
FACEBOOK_SECRET=XX
GOOGLE_CLIENT_EMAIL=XX
GOOGLE_PRIVATE_KEY=XX
GOOGLE_PROJECTID=XX
GOOGLE_BUCKET_NAME=edge-next
GITHUB_ID=XX
GITHUB_SECRET=XX
GOOGLE_ID=XX
GOOGLE_SECRET
NEXT_PUBLIC_GA_TRACKING_ID=xx
````

As you can see here there are many third-party tools and services that are needed to run a full-fledged service. But do not worry, setting up these accounts is something easy and here there are some tips:

- [Register your Github application](https://developer.github.com/v3/guides/basics-of-authentication/)
- [Register your Google application](https://developers.google.com/identity/sign-in/web/sign-in)
- [Register your Facebook application](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/)
- [Get a sendgrid API key](https://www.youtube.com/watch?v=ShOQxpX7Dcw)
- [Create a Mongo Atlas account](https://docs.mongodb.com/guides/cloud/connectionstring/)
- [Create a Google cloud bucket](https://cloud.google.com/storage/docs/creating-buckets) & [Making files public in google bucket](https://cloud.google.com/storage/docs/access-control/making-data-public)
- [Get a Google Maps API key](https://developers.google.com/maps/documentation/javascript/get-api-key?hl=es-419)

-----

## How can I hack Edge?

Anyway...! You don't need to use all the services listed there. You can just use some of the features Edge offers. Think of Edge (at the moment) like Hackathon Starter on steroids. You can delete or adapt any of it's logic.

## Feedback and contributions

We are looking for people who can share HONEST feedback with us, makes us grow and give value back to the community. 


## API 

This is the API that Edge exposes as of version 1.0

### Auth
- `POST /api/auth/login`
  - `{ email: xxx@xxx.com, password: password}`
  - Logs in a user
- `GET /api/auth/logout`
  - Logout a user
- `GET /api/auth/reset-password?email=xxx@xxx.com`
  - Marks the user for reset password, sends an email with a token
- `POST /api/auth/reset-password`
  - `{email: xxx@xxx.com, password: NewPassword, token: token }`
  - Enables de new password for a user
- `GET /api/auth/verify?email=xxx@xxx.com&token=TOKEN`
  - Verifies a user email

### Users
- `GET /api/users`
  - Access limited to users with permission `user.list` or `user.admin`
- `GET /api/users/ID` | `GET /api/users/me` | `GET /api/users/@username`
  - Access limited to own user or users with permission `user.read` or `user.admin` (or own user)
- `POST /api/users`
  - Access limited to users with permission `user.create`. Default is public, to allow users to register.
- `PUT /api/users/ID`
  - Access limited to own user or users with permission `user.admin` and `user.update`
  - To update a user the different endpoint sufixes have to be added
  - `PUT /api/users/ID/profile`
 
  - `PUT /api/users/ID/email`

  - `PUT /api/users/ID/username`
   
  - `PUT /api/users/ID/picture`
   
  - `PUT /api/users/ID/password`
  
  - `PUT /api/users/ID/block`
   
- `DELETE /api/users/ID`
  - Access limited to own user or users with permission `user.admin` and `user.delete`. For the current user is also required to send a `password` query parameter.

### Content
- `GET /api/content/[TYPE]`
  - Access limited to users with permission `content.TYPE.read` or `content.TYPE.admin`
- `GET /api/content/[TYPE]/[CONTENT_SLUG]` | `GET /api/content/[TYPE]/[CONTENT_ID]?field=id`
  - Access limited to own user or users with permission `content.TYPE.read` or `content.TYPE.admin`
- `POST /api/content/[TYPE]`
  - Access limited to `content.TYPE.admin`, or `content.TYPE.create`
- `PUT /api/content/[TYPE]/[CONTENT_SLUG]` | `POST /api/content/[TYPE]/[CONTENT_SLUG]` |  `PUT /api/content/[TYPE]/[CONTENT_ID]?field=id` |  `POST /api/content/[TYPE]/[CONTENT_ID]?field=id`
  - Access limited to own user or users with permission `content.TYPE.admin` or `content.TYPE.update`
- `DELETE /api/content/[TYPE]/[CONTENT_SLUG]` | `GET /api/content/[TYPE]/[CONTENT_ID]?field=id`
  - Access limited to own user or users with permission `content.TYPE.admin` or `content.TYPE.delete`

### Comments

- `GET /api/comments?contentType=CONTENT_TYPE`
  - Access limited to users with permission `content.TYPE.comments.read` or `content.TYPE.comments.admin`. If no CONTENT_TYPE is specified, it will list all the comments that the current user has access to.
  - Other filters available are `contentId`, `author` (user id), `conversationId` (can be set to the string `'false'` to ellicit empty conversationIds)

- `POST /api/comments?contentId=CONTENT_ID&contentType=CONTENT_TYPE`
  - Access limited to `content.TYPE.comments.admin`, or `content.TYPE.comments.create`

- `GET /api/comments/[COMMENT_SLUG]` or `GET /api/comments/[COMMENT_ID]?field=id` 
  - Access limited to own user or users with permission `content.TYPE.comments.read` or `content.TYPE.comments.admin`
- `DELETE /api/comments/[COMMENT_SLUG]` or `DELETE /api/comments/[COMMENT_ID]?field=id` 
  - Access limited to own user or users with permission `content.TYPE.comments.admin` or `content.TYPE.comments.delete`

### Activity

- `GET /api/activity/[USER_ID]`
  - Returns a list of activity for the user, access limited to own user or users with permission `activity.read` or `activity.admin`





I hope some of you get to use Edge and can give us some feedback or collaborate on the open source initiative.

Thanks !