Tag: Comments

Lazy Load Routes in Vue with webpack Dynamic Comments

The way routing works in JavaScript is usually that you specify which relative URL pattern you want for which component to render. So for /about you want the <About /> component to render. Let’s take a look at how to do this in Vue/Vue Router with lazy loading, and do it as cleanly as possible. I use this little tip all the time in my own work.

A repo that includes everything covered in this post is available on GitHub.

You’ve probably seen Vue routes (URLs) like this:

import Vue from 'vue' import VueRouter from 'vue-router'  import Home from '../views/Home.vue' import About from '../views/About.vue' import Login from '../views/Login.vue'  Vue.use(VueRouter)  const routes = [   { path: '/', name: 'Home', component: Home },   { path: '/about', name: 'About', component: About },   { path: '/login', name: 'Login', component: Login } ]  const router = new VueRouter({   routes })  export default router

That will load the <Home /> component at the / route, the <About /> component at the /about route, and the <Login /> component at the /login route.

That doesn’t do a very good job of code splitting though, since all three of those components will be bundled together rather than loaded dynamically as needed.

This is a terminal screenshot with a dark purple background with text in white green and blue. The content shows the final build after compiling.

Here’s another way to do the same, only with code splitting with dynamic import statements and webpack chunk names:

const routes = [   {     path: '/',     name: 'Home',     component: () => import(/* webpackChunkName: "Home" */ '../views/Home.vue')   },   {     path: '/about',     name: 'About',     component: () => import(/* webpackChunkName: "About" */ '../views/About.vue')   },   {     path: '/login',     name: 'Login',     component: () => import(/* webpackChunkName: "Login" */ '../views/Login.vue')   } ]

This is perfectly fine and doesn’t have any major downsides, other than being a bit verbose and repetitive. Since we’re awesome developers, let’s do a bit of abstraction to help, using an array that we’ll .map over.

const routeOptions = [   { path: '/', name: 'Home' },   { path: '/about', name: 'About' },   { path: '/login', name: 'Login' } ]  const routes = routeOptions.map(route => {   return {     ...route,     component: () => import(`@/views/$ {route.name}.vue`)   } })  const router = new VueRouter({   routes })

Now we’ve reduced the use of the component key by using the route name as param in the import function.

But what happens if we want to set the chunk name?

As far as I know, you can’t have dynamic comments in JavaScript without some kind of build step. So, we are sacrificing comments (webpackChunkName) in favor of having to write less code in this case. It’s entirely up to you which you prefer.

Just kidding, let’s fix it.

As of webpack 2.6.0 , the placeholders [index] and [request] are supported, meaning we can set the name of the generated chunk like this:

// ...  const routeOptions = [   { path: '/', name: 'Home' },   { path: '/about', name: 'About' },   { path: '/login', name: 'Login' } ]  const routes = routeOptions.map(route => {   return {     ...route,     component: () => import(/* webpackChunkName: "[request]" */ `../views/$ {route.name}.vue`)   } })  const router = new VueRouter({   routes })

Nice! Now we have all the power, plus dynamically loaded routes with named chunks. And it works with Vue 2 and Vue 3. You can check it out by running npm run build in the terminal:

This is the same terminal screenshot as before, but with three of the JavaScript built files highlighted with the words "Named Chunks" annotated beside them.
See that? Now the components are chunked out… and the build did all the naming for us!

Buuuuut, we can still take this one step further by grouping the lazy loaded routes into named chunks rather than individual components. For example, we can create groups that group our most important components together and the rest in another “not so important” group. We merely update the webpack chunk name in place of the [request] placeholder we used earlier:

const routes = [   {     path: "/",     name: "Home",     component: () =>       import(/* webpackChunkName: "VeryImportantThings" */ "../views/Home.vue")   },   {     path: "/about",     name: "About",     component: () =>       import(/* webpackChunkName: "VeryImportantThings" */ "../views/About.vue")   },   {     path: "/login",     name: "Login",     component: () =>       import(/* webpackChunkName: "NotSoImportant" */ "../views/Login.vue")   },   {     path: "/contact",     name: "Contact",     component: () =>       import(/* webpackChunkName: "NotSoImportant" */ "../views/Contact.vue")   } ];

Now our four components are groups into two separate chunks.

The same terminal with different compiled JavaScript files.

There you have it! A technique for lazy loading routes in Vue, plus some ideas for how to name and group them together at build.


The post Lazy Load Routes in Vue with webpack Dynamic Comments appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , , ,

My WordPress Comments Wishlist

A built-in commenting system is one of the reasons people reach for WordPress (and often stay there long-term). While I do think having a comment system is compelling (and as big of a fan of building on WordPress as I am), I find the comments system on WordPress quite crusty. It needs some love! There is so much more potential there! Here’s my list.

I don’t have any inside WordPress knowledge to inform me about how difficult any of these ideas would be, what other things they may affect, and what conversations have already been had around them. While I personally like these ideas, I’m fully aware that software decisions, particularly at this scale, are not lightly made. So all that said, this wishlist is almost like a design exercise and could be considered user feedback.

Comments should be user-owned and editable.

I find it highly weird that a logged-in user can leave a comment, but the comment isn’t “owned” by them. There doesn’t seem to be a direct connection between their account and the comment they just left. Seems like if you actually have an account, that would be an obvious thing to attach. People leave typos in comments all the time and it would be much less frustrating for them if they could just edit them. Maybe there could be a way to offer that edibility even without an account, like some editing timeout window.

As an admin user, I can edit comments in the admin area. This is what I’d expect a logged in user could do on their own comment.

Is this something BuddyPress does? I don’t know. I know with bbPress that users own (and thus can edit) their topics and replies (possibly time-limited), but that functionality doesn’t seem to extend to post comment threads.

There should be social auth for comments.

Having to manually type out your name and email address and all that to leave a comment feels like too much effort these days. I’d bet that alone detracts many would-be commenters. Commenting systems like Disqus make this quick and easy, and with social media I’m so used to being able to type a reply and respond immediately. On a WordPress comment form, I should be able to click a button to have the legwork of knowing my name and email and such taken care of for me. That might even be my ticket for editing it later.

Jetpack offers social media auth for comments, but if you turn that on, the UI for commenting is <iframe>d, so you have no design control or anything.

Also, the UI where it first shows up as a little narrow textarea block that you click into to expand into a comment area is also unchangeable and just doesn’t work that well with my style. I wouldn’t mind if this was Jetpack-powered functionality, I just want more control.

The login form you get from Jetpack, which is like WordPress.com

There should be a HTML tag whitelist.

I find when people type a <div>, they don’t expect to have to escape it lest it be stripped. They expect it to just show <div>. Even web developers.

I see people “screw up” (not entirely their fault) the HTML in comments like this a ton. Jetpack offers Markdown in comments, which is a massive improvement because it becomes so easy to use backticks. I think native WordPress should support that. But even then, not everyone knows Markdown, let alone how it deals with HTML (e.g. when does it escape HTML and when does it not).

I’ve been thinking about this for a decade and I’m still not sure the best solution, but a whitelist seems like it could help a lot. For example, you can use a <em> and it will make text italic, but a tag like <section> is not on the whitelist and is automatically escaped.

Comments should be previewable.

A preview gives people a chance to make sure their comment looks right, and probably just as importantly, one more chance to think before hitting the submit button.

Replies should generate email notifications.

Jetpack offers a feature that allows users to subscribe either to your blog itself (email notifications of newly published posts) or to comments on the particular post the user is commenting on.

In the case of new blog post emails, those come from WordPress.com, and you don’t have any control over them (e.g. design control or control over what kind of posts trigger them). It’s still kind of a cool feature, but if you’re serious about delivering new content to users, you might be better off with a more custom workflow.

Notifying users of new comments seems like a great feature for any commenting system. When I leave a comment, I feel invested, and there is a good chance I want to follow the continued conversation. Although, even more likely, I’d just want to hear about replies to my specific comment. WordPress already generates so many emails for things, this doesn’t feel out of scope.

Replies should show parent comment(s).

When looking at the site itself, replies are fairly obvious. They are nested under the parent comment they reply to. Context is always there. But there are other places where you can see a reply comment and be totally missing that context:

  1. Email notifications of reply comments don’t include the parent thread
  2. The comments area in the admin (or WordPress app)

The later includes a “In Reply To [Name]” link, but all it does is link to the front end of the site where that parent comment lives, it doesn’t do anything extra helpful like expand inline or show a popup preview.

Comment emails should be better looking.

I have a plugin on CSS-Tricks called Clean Notifications that hasn’t been updated in 13 years and it still works just fine. All it does is clean up the emails so there aren’t long gnarly URL’s in them, and instead, just have regular HTML links.

Default new comment emails: full of long gnarly URLs

With Clean Notifications on, things are cleaned up a little.

I’d vote that the default WordPress-generated emails could have a whole round of design love. Basic HTML email usage would allow link usage and basic typography that would make them all much nicer.

Look how nice and simple Lee Monroe’s HTML email template is.

There are links to Delete and Spam a comment, but they don’t actually do those things, they take you to a page where then you have to click another link to perform the action. If I’m auth’d, it should just do the action.

Ajax

Comment actions (particularly leaving a new comment) should be doable without requiring a full page refresh. Full page refreshes feel old in the same way that lacking quick social auth feels old.

Comment replies already have a special script that gets enqueued on WordPress themes. That script handles the job of manipulating the DOM and moving the comment form up next to comments when a “Reply” link is clicked (if you enable that feature). So there is a precedent for comment-specific JavaScript on arbitrary themes.

I would think it’s possible to write more JavaScript that would allow for Ajax submission of new comments and DOM manipulation to do whatever happens next (show the comment, show approval messaging, show errors, etc). There is precedent for this, as well as third-party plugins and blog posts about hand-rolled implementations. Personally, I just don’t want that technical debt, I just want it to work.

More comment actions

I’ve long run a plugin to help me “feature” or “bury” comments in a thread. It’s not particularly complex, as it just updates some metadata on individual comments, then lets me apply those states with a class and style them in CSS. I don’t know that all sites need this kind of thing, but… Jetpack offers the ability to add a button to “Like” a post like you can on WordPress.com. Why not comments too? If people could vote on comments, it could do useful things like allow the default sort of comments to be based on up-votes or likes rather than chronological order alone. I think people care far more about interesting comments than they do about seeing them in date-time order.

So perhaps additional comment actions could be…

  • Upvote
  • Downvote
  • Report as spam
  • Report as harmful (or a Code of Conduct violation)
  • Save / Pin

Speaking of voting, if comments were owned by users, and comments had data about quality, perhaps users with lots of good comments could be rewarded in various ways. Right now, you essentially have to choose to either moderate all comments or not, but it could be that you only moderate comments from people with low/bad/no quality scores. Not to mention calling out comments in threads from known-good commenters.

Sorting

Assuming we get some sort of voting system for comments, it makes sense for comments to be ordered by votes by default. Or at least an option for sorting in addition to the chronological order.

Front-end powers

I think it would be neat if you could do all the things you can do on the back end with a comment on the front end. For example, edit the comment, delete it, spam it, update metadata, etc.

Permissions role for comment moderator

On sites with thriving comment threads (like all sites would be if they had these awesome changes amiright?) it would be nice to be able to invite trusted community members to moderate comment threads. Not admins of the whole site. Not authors or editors. Just people who have permission to deal with comments and comments alone.

Not a real thing.


This was partially inspired by Jeremy Felt’s recent post and partially a continuation of my own thoughts. Jeremy mentions ideas like private comments (interesting, but not mega compelling to me) and Webmentions support (yes please!). Maybe this will go somewhere.


The post My WordPress Comments Wishlist appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, ,
[Top]

Roll Your Own Comments With Gatsby and FaunaDB

If you haven’t used Gatsby before have a read about why it’s fast in every way that matters, and if you haven’t used FaunaDB before you’re in for a treat. If you’re looking to make your static sites full blown Jamstack applications this is the back end solution for you!

This tutorial will only focus on the operations you need to use FaunaDB to power a comment system for a Gatsby blog. The app comes complete with inputs fields that allow users to comment on your posts and an admin area for you to approve or delete comments before they appear on each post. Authentication is provided by Netlify’s Identity widget and it’s all sewn together using Netlify serverless functions and an Apollo/GraphQL API that pushes data up to a FaunaDB database collection.

I chose FaunaDB for the database for a number of reasons. Firstly there’s a very generous free tier! perfect for those small projects that need a back end, there’s native support for GraphQL queries and it has some really powerful indexing features!

…and to quote the creators;

No matter which stack you use, or where you’re deploying your app, FaunaDB gives you effortless, low-latency and reliable access to your data via APIs familiar to you

You can see the finished comments app here.

Get Started

To get started clone the repo at https://github.com/PaulieScanlon/fauna-gatsby-comments

or:

git clone https://github.com/PaulieScanlon/fauna-gatsby-comments.git

Then install all the dependencies:

npm install

Also cd in to functions/apollo-graphql and install the dependencies for the Netlify function:

npm install

This is a separate package and has its own dependencies, you’ll be using this later.

We also need to install the Netlify CLI as you’ll also use this later:

npm install netlify-cli -g

Now lets add three new files that aren’t part of the repo.

At the root of your project create a .env .env.development and .env.production

Add the following to .env:

GATSBY_FAUNA_DB = GATSBY_FAUNA_COLLECTION =

Add the following to .env.development:

GATSBY_FAUNA_DB = GATSBY_FAUNA_COLLECTION = GATSBY_SHOW_SIGN_UP = true GATSBY_ADMIN_ID =

Add the following to .env.production:

GATSBY_FAUNA_DB = GATSBY_FAUNA_COLLECTION = GATSBY_SHOW_SIGN_UP = false GATSBY_ADMIN_ID =

You’ll come back to these later but in case you’re wondering

  • GATSBY_FAUNA_DB is the FaunaDB secret key for your database
  • GATSBY_FAUNA_COLLECTION is the FaunaDB collection name
  • GATSBY_SHOW_SIGN_UP is used to hide the Sign up button when the site is in production
  • GATSBY_ADMIN_ID is a user id that Netlify Identity will generate for you

If you’re the curious type you can get a taster of the app by running gatsby develop or yarn develop and then navigate to http://localhost:8000 in your browser.

FaunaDB

So Let’s get cracking, but before we write any operations head over to https://fauna.com/ and sign up!

Database and Collection

  • Create a new database by clicking NEW DATABASE
  • Name the database: I’ve called the demo database fauna-gatsby-comments
  • Create a new Collection by clicking NEW COLLECTION
  • Name the collection: I’ve called the demo collection demo-blog-comments

Server Key

Now you’ll need to to set up a server key. Go to SECURITY

  • Create a new key by clicking NEW KEY
  • Select the database you want the key to apply to, fauna-gatsby-comments for example
  • Set the Role as Admin
  • Name the server key: I’ve called the demo key demo-blog-server-key

Environment Variables Pt. 1

Copy the server key and add it to GATSBY_FAUNA_DB in .env.development, .env.production and .env.

You’ll also need to add the name of the collection to GATSBY_FAUNA_COLLECTION in .env.development, .env.production and .env.

Adding these values to .env are just so you can test your development FaunaDB operations, which you’ll do next.

Let’s start by creating a comment so head back to boop.js:

// boop.js ... // CREATE COMMENT createComment: async () => {   const slug = "/posts/some-post"   const name = "some name"   const comment = "some comment"   const results = await client.query(     q.Create(q.Collection(COLLECTION_NAME), {       data: {         isApproved: false,         slug: slug,         date: new Date().toString(),         name: name,         comment: comment,       },     })   )   console.log(JSON.stringify(results, null, 2))   return {     commentId: results.ref.id,   } }, ...

The breakdown of this function is as follows;

  • q is the instance of faunadb.query
  • Create is the FaunaDB method to create an entry within a collection
  • Collection is area in the database to store the data. It takes the name of the collection as the first argument and a data object as the second.

The second argument is the shape of the data you need to drive the applications comment system.

For now you’re going to hard-code slugname and comment but in the final app these values are captured by the input form on the posts page and passed in via args

The breakdown for the shape is as follows;

  • isApproved is the status of the comment and by default it’s false until we approve it in the Admin page
  • slug is the path to the post where the comment was written
  • date is the time stamp the comment was written
  • name is the name the user entered in the comments from
  • comment is the comment the user entered in the comments form

When you (or a user) creates a comment you’re not really interested in dealing with the response because as far as the user is concerned all they’ll see is either a success or error message.

After a user has posted a comment it will go in to your Admin queue until you approve it but if you did want to return something you could surface this in the UI by returning something from the createComment function.

Create a comment

If you’ve hard coded a slugname and comment you can now run the following in your CLI

node boop createComment

If everything worked correctly you should see a log in your terminal of the new comment.

{    "ref": {      "@ref": {        "id": "263413122555970050",        "collection": {          "@ref": {            "id": "demo-blog-comments",            "collection": {              "@ref": {                "id": "collections"              }            }          }        }      }    },    "ts": 1587469179600000,    "data": {      "isApproved": false,      "slug": "/posts/some-post",      "date": "Tue Apr 21 2020 12:39:39 GMT+0100 (British Summer Time)",      "name": "some name",      "comment": "some comment"    }  }  { commentId: '263413122555970050' }

If you head over to COLLECTIONS in FaunaDB you should see your new entry in the collection.

You’ll need to create a few more comments while in development so change the hard-coded values for name and comment and run the following again.

node boop createComment

Do this a few times so you end up with at least three new comments stored in the database, you’ll use these in a moment.

Delete comment by id

Now that you can create comments you’ll also need to be able to delete a comment.

By adding the commentId of one of the comments you created above you can delete it from the database. The commentId is the id in the ref.@ref object

Again you’re not really concerned with the return value here but if you wanted to surface this in the UI you could do so by returning something from the deleteCommentById function.

// boop.js ... // DELETE COMMENT deleteCommentById: async () => {   const commentId = "263413122555970050";   const results = await client.query(     q.Delete(q.Ref(q.Collection(COLLECTION_NAME), commentId))   );   console.log(JSON.stringify(results, null, 2));   return {     commentId: results.ref.id,   }; }, ...

The breakdown of this function is as follows

  • client is the FaunaDB client instance
  • query is a method to get data from FaunaDB
  • q is the instance of faunadb.query
  • Delete is the FaunaDB delete method to delete entries from a collection
  • Ref is the unique FaunaDB ref used to identify the entry
  • Collection is area in the database where the data is stored

If you’ve hard coded a commentId you can now run the following in your CLI:

node boop deleteCommentById

If you head back over to COLLECTIONS in FaunaDB you should see that entry no longer exists in collection

Indexes

Next you’re going to create an INDEX in FaunaDB.

An INDEX allows you to query the database with a specific term and define a specific data shape to return.

When working with GraphQL and / or TypeScript this is really powerful because you can use FaunaDB indexes to return only the data you need and in a predictable shape. This makes data typing responses in GraphQL and / TypeScript a dream… I’ve worked on a number of applications that just return a massive object of useless values which will inevitably cause bugs in your app. blurg!

  • Go to INDEXES and click NEW INDEX
  • Name the index: I’ve called this one get-all-comments
  • Set the source collection to the name of the collection you setup earlier

As mentioned above when you query the database using this index you can tell FaunaDB which parts of the entry you want to return.

You can do this by adding “values” but be careful to enter the values exactly as they appear below because (on the FaunaDB free tier) you can’t amend these after you’ve created them so if there’s a mistake you’ll have to delete the index and start again… bummer!

The values you need to add are as follows:

  • ref
  • data.isApproved
  • data.slug
  • data.date
  • data.name
  • data.comment

After you’ve added all the values you can click SAVE.

Get all comments

// boop.js ... // GET ALL COMMENTS getAllComments: async () => {    const results = await client.query(      q.Paginate(q.Match(q.Index("get-all-comments")))    );    console.log(JSON.stringify(results, null, 2));    return results.data.map(([ref, isApproved, slug, date, name, comment]) => ({      commentId: ref.id,      isApproved,      slug,      date,      name,      comment,    }));  }, ...

The breakdown of this function is as follows

  • client is the FaunaDB client instance
  • query is a method to get data from FaunaDB
  • q is the instance of faunadb.query
  • Paginate paginates the responses
  • Match returns matched results
  • Index is the name of the Index you just created

The shape of the returned result here is an array of the same shape you defined in the Index “values”

If you run the following you should see the list of all the comments you created earlier:

node boop getAllComments

Get comments by slug

You’re going to take a similar approach as above but this time create a new Index that allows you to query FaunaDB in a different way. The key difference here is that when you get-comments-by-slug you’ll need to tell FaunaDB about this specific term and you can do this by adding data.slug to the Terms field.

  • Go to INDEX and click NEW INDEX
  • Name the index, I’ve called this one get-comments-by-slug
  • Set the source collection to the name of the collection you setup earlier
  • Add data.slug in the terms field

The values you need to add are as follows:

  • ref
  • data.isApproved
  • data.slug
  • data.date
  • data.name
  • data.comment

After you’ve added all the values you can click SAVE.

// boop.js ... // GET COMMENT BY SLUG getCommentsBySlug: async () => {   const slug = "/posts/some-post";   const results = await client.query(     q.Paginate(q.Match(q.Index("get-comments-by-slug"), slug))   );   console.log(JSON.stringify(results, null, 2));   return results.data.map(([ref, isApproved, slug, date, name, comment]) => ({     commentId: ref.id,     isApproved,     slug,     date,     name,     comment,   })); }, ...

The breakdown of this function is as follows:

  • client is the FaunaDB client instance
  • query is a method to get data from FaunaDB
  • q is the instance of faunadb.query
  • Paginate paginates the responses
  • Match returns matched results
  • Index is the name of the Index you just created

The shape of the returned result here is an array of the same shape you defined in the Index “values” you can create this shape in the same way you did above and be sure to add a value for terms. Again be careful to enter these with care.

If you run the following you should see the list of all the comments you created earlier but for a specific slug:

node boop getCommentsBySlug

Approve comment by id

When you create a comment you manually set the isApproved value to false. This prevents the comment from being shown in the app until you approve it.

You’ll now need to create a function to do this but you’ll need to hard-code a commentId. Use a commentId from one of the comments you created earlier:

// boop.js ... // APPROVE COMMENT BY ID approveCommentById: async () => {   const commentId = '263413122555970050'   const results = await client.query(     q.Update(q.Ref(q.Collection(COLLECTION_NAME), commentId), {       data: {         isApproved: true,       },     })   );   console.log(JSON.stringify(results, null, 2));   return {     isApproved: results.isApproved,   }; }, ...

The breakdown of this function is as follows:

  • client is the FaunaDB client instance
  • query is a method to get data from FaunaDB
  • q is the instance of faunadb.query
  • Update is the FaundaDB method up update an entry
  • Ref is the unique FaunaDB ref used to identify the entry
  • Collection is area in the database where the data is stored

If you’ve hard coded a commentId you can now run the following in your CLI:

node boop approveCommentById

If you run the getCommentsBySlug again you should now see the isApproved status of the entry you hard-coded the commentId for will have changed to true.

node boop getCommentsBySlug

These are all the operations required to manage the data from the app.

In the repo if you have a look at apollo-graphql.js which can be found in functions/apollo-graphql you’ll see the all of the above operations. As mentioned before the hard-coded values are replaced by args, these are the values passed in from various parts of the app.

Netlify

Assuming you’ve completed the Netlify sign up process or already have an account with Netlify you can now push the demo app to your GitHub account.

To do this you’ll need to have initialize git locally, added a remote and have pushed the demo repo upstream before proceeding.

You should now be able to link the repo up to Netlify’s Continuous Deployment.

If you click the “New site from Git” button on the Netlify dashboard you can authorize access to your GitHub account and select the gatsby-fauna-comments repo to enable Netlify’s Continuous Deployment. You’ll need to have deployed at least once so that we have a pubic URL of your app.

The URL will look something like this https://ecstatic-lewin-b1bd17.netlify.app but feel free to rename it and make a note of the URL as you’ll need it for the Netlify Identity step mentioned shortly.

Environment Variables Pt. 2

In a previous step you added the FaunaDB database secret key and collection name to your .env files(s). You’ll also need to add the same to Netlify’s Environment variables.

  • Navigate to Settings from the Netlify navigation
  • Click on Build and deploy
  • Either select Environment or scroll down until you see Environment variables
  • Click on Edit variables

Proceed to add the following:

GATSBY_SHOW_SIGN_UP = false GATSBY_FAUNA_DB = you FaunaDB secret key GATSBY_FAUNA_COLLECTION = you FaunaDB collection name

While you’re here you’ll also need to amend the Sensitive variable policy, select Deploy without restrictions

Netlify Identity Widget

I mentioned before that when a comment is created the isApproved value is set to false, this prevents comments from appearing on blog posts until you (the admin) have approved them. In order to become admin you’ll need to create an identity.

You can achieve this by using the Netlify Identity Widget.

If you’ve completed the Continuous Deployment step above you can navigate to the Identity page from the Netlify navigation.

You wont see any users in here just yet so lets use the app to connect the dots, but before you do that make sure you click Enable Identity

Before you continue I just want to point out you’ll be using netlify dev instead of gatsby develop or yarn develop from now on. This is because you’ll be using some “special” Netlify methods in the app and staring the server using netlify dev is required to spin up various processes you’ll be using.

  • Spin up the app using netlify dev
  • Navigate to http://localhost:8888/admin/
  • Click the Sign Up button in the header

You will also need to point the Netlify Identity widget at your newly deployed app URL. This was the URL I mentioned you’ll need to make a note of earlier, if you’ve not renamed your app it’ll look something like this https://ecstatic-lewin-b1bd17.netlify.app/ There will be a prompt in the pop up window to Set site’s URL.

You can now complete the necessary sign up steps.

After sign up you’ll get an email asking you to confirm you identity and once that’s completed refresh the Identity page in Netlify and you should see yourself as a user.

It’s now login time, but before you do this find Identity.js in src/components and temporarily un-comment the console.log() on line 14. This will log the Netlify Identity user object to the console.

  • Restart your local server
  • Spin up the app again using netlify dev
  • Click the Login button in the header

If this all works you should be able to see a console log for netlifyIdentity.currentUser: find the id key and copy the value.

Set this as the value for GATSBY_ADMIN_ID = in both .env.production and .env.development

You can now safely remove the console.log() on line 14 in Identity.js or just comment it out again.

GATSBY_ADMIN_ID = your Netlify Identity user id

…and finally

  • Restart your local server
  • Spin up the app again using netlify dev

Now you should be able to login as “Admin”… hooray!

Navigate to http://localhost:8888/admin/ and Login.

It’s important to note here you’ll be using localhost:8888 for development now and NOT localhost:8000 which is more common with Gatsby development

Before you test this in the deployed environment make sure you go back to Netlify’s Environment variables and add your Netlify Identity user id to the Environment variables!

  • Navigate to Settings from the Netlify navigation
  • Click on Build and deploy
  • Either select Environment or scroll down until you see Environment variables
  • Click on Edit variables

Proceed to add the following:

GATSBY_ADMIN_ID = your Netlify Identity user id

If you have a play around with the app and enter a few comments on each of the posts then navigate back to Admin page you can choose to either approve or delete the comments.

Naturally only approved comments will be displayed on any given post and deleted ones are gone forever.

If you’ve used this tutorial for your project I’d love to hear from you at @pauliescanlon.


By Paulie Scanlon (@pauliescanlon), Front End React UI Developer / UX Engineer: After all is said and done, structure + order = fun.

Visit Paulie’s Blog at: www.paulie.dev

The post Roll Your Own Comments With Gatsby and FaunaDB appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

Rethinking Code Comments

Justin Duke asks if treating code comments like footnotes could help us understand the code in a file better. In his mockup, all the comments are hidden by default and require a click to reveal:

What a neat idea! Justin’s design reminds me of the way that Instapaper treated inline footnotes.

Instapaper (circa 2012)

I guess the reason I like this idea so much is that a lot of comments don’t need to be read constantly, — they’re sort of a reminder that, “Hey, this needs work in the future” or “Yikes, this is weird and I’m sorry.” Keeping these comments out of the code makes it much easier to scan the whole file, too.

I do wonder if there could be a toggle that shows every comment, just in case you need to read all the comments in sequence rather than clicking to toggle each one.

Anyway, all this talk about comments reminds me of an absolutely fantastic talk by Sarah Drasner at JSConf this year where she discussed why comments are so dang hard to get right:

Direct Link to ArticlePermalink

The post Rethinking Code Comments appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Render Snarky Comments in Comic Sans

Hilarious idea by Zach Leatherman. To test if a comment is “snarky” or not, there is an npm package up to the task.

On this site, we generally just delete snarky comments, but I still run a WordPress plugin that allows me to “feature” or “bury” comments. It’s old but it still works fine in the latest WordPress. We use the bury functionality for comments that aren’t rude, snarky, or spam, but also don’t add much to the post. We try to downplay those so they aren’t wasting people’s time scrolling through the threads.

I dig the Comic Sans idea, so I’m gonna give it a shot. 😉

Direct Link to ArticlePermalink

The post Render Snarky Comments in Comic Sans appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]