How to rename your React Native project

Renaming your React Native project after it has been initialized is a hassle. React Native has a default way of being initialized which allows you to name your project from the start. This is achieved because the CLI uses the name you specify to create your Xcode and Android projects during setup. That’s a very handy feature, but what if you need to change the name of your project down the road? What’s the best way to rename your React Native project?

Without the right tool, you will quickly find yourself in a rabbit-hole of find-and-replace activity. Xcode and Android Studio errors can arise and cost you more time than you’re willing to spend investigating. Whether you began with react-native init or a starter kit you found online, read on to learn how to rename your React Native project the easy way.

Using a starter kit

When working with React Native, you have many options to help get you started. We have the default npx react-native init AwesomeProject which is the most basic form of initialization (https://reactnative.dev/docs/getting-started), but we also have many other ways to get the ball rolling.

There are many options available on https://codecanyon.com, https://code.market/, and other marketplaces as well as individual teams working on boilerplate templates. One of the most popular is https://infinite.red/ignite, but my personal favorite is React Native Starter from the Flat Logic team. Not only do they have React Native templates, they also Vue, React, and Angular templates for desktop apps.

Code templates that help you bootstrap your app code-wise can really benefit you in terms of time and money saved. These templates come with features like i18n (internationalization), testing setups, code formatting configurations, a pre-filled .gitignore file, and more. These are boilerplate items that we typically end up adding to our app anyway.

These kits can come with lots of features that you may not need and you can obviously strip those out. As for the parts that must stay we need a good approach to updating them. Code aside, I’m talking about configuration tasks like bundleID, package.json entries, and the name of the app.

Bootstrapping with a starter kit is one of the main reasons you may find yourself needing to rename your app.

Renaming your app

When you’re ready to rename your React Native project, there are quite a few updates you’ll need to make. The init step named the proper components, but now you need to find and change them all.

For starters, there’s your package.json file “name” entry and app.json if you have one. Next your ios project needs to have the following updated:

  • .xcodeproj or .xcworkspace file
  • schemas
  • test schemas
  • AppDelegate.m module name
  • more configurations in Xcode
VS Code screen capture highlighting "AwesomeApp" naming set by npm react-native init (iOS)

Then there’s the Android side of the house:

  • gradle settings
  • applicationId
  • package name
  • main component name
  • and more…
VS Code screen capture highlighting "AwesomeApp" naming set by npm react-native init (Android)

This may not seem like many updates to make, but there are several more changes you’ll need to chase down. Even when you do find them, making sure everything is in sync can quickly get out of hand. I can safely assume that if you’ve made it this far in the article you’ve already experienced enough strife. You get my point.

React-native-rename

In walks https://www.npmjs.com/package/react-native-rename to save the day. With one command, this package will sweep through your iOS and Android directories performing most of these changes for you! It makes it effortless to rename your React Native project.

The first step is to add the package globally:

yarn global add react-native-rename or npm install react-native-rename -g

This makes sure that it’s available for use no matter which project you need to rename. Due to the nature of its utility, there’s no need to install this as a dependency of any particular project.

Next, switch to a new branch in case anything goes awry:

git checkout -b rename-app

You can of course merge this branch back into the main stream once you verify everything works.

Lastly, run the react-native-rename command to set the rename in motion. For example if your want to rename your project “JS Tuts” and your bundle ID is “io.neroscript.jstuts” you’d execute:

react-native-rename "JS Tuts" -b io.neroscript.jstuts

It provides feedback on all of the items it could or couldn’t change.

Note that the bundleID will change automatically for Android, but for iOS you’ll have to update it manually in Xcode.

Make sure you select the correct target, then the “General” header to find and update your Bundle Identifier

Pretty Printing Your Site with JavaScript


Visit one of your favorite sites, print a page, and check the format of the print preview. Chances are it doesn’t come out very well-formatted. Understandably, printing things from the web may not be something your users do on a regular basis, but for the sites with users who do print confirmation pages, item lists, quotes, etc. there is a better way to pretty print your site with JavaScript!


TLDR;

Using JavaScript alone, I’ll show you how to create a pretty print page derived from elements currently in the DOM of any page. There is no need to make any additional network requests and no need for any server-side development. By simply cloning the elements of the page that you want to print, you can rebuild your pretty print page seamlessly.

This process cannot override the default browser print functionality, but it provides a more customized and useful print experience for your users.


The traditional approach

Printing exactly what’s on the page and leaving it up to the browser to figure out what to do is often not the best approach. The generic approach to combat this is to struggle with a print.css file and hide enough elements to make your page appear presentable. The print.css approach can be a hassle, and all too often, still only gets you halfway to where you want to be.

Upgrading your print functionality

Create a blank canvas 

First off, you’ll need to create a “canvas” to paint on since the page you want to print already has its own DOM filled with elements that you may or may not need. Elements like the header, footer, call-to-action buttons, unused filters, navigation bars, tab bars, backgrounds, and large images, etc. may not serve much of a purpose on a printed page. There are two traditional approaches to making your page print-ready: 

1) Add a @media print media query in an existing CSS file to hide all of the unneeded elements on the page.

@media print {
/* This media query only applies itself to the page during printing */
header, footer, nav, .btn--call-to-action {
display: none !important;
}
}

2) Include an external stylesheet with the media attribute value of print and house all of the CSS you want to apply to the page during printing, inside of it.

<link href="styles/print.css" rel="stylesheet" media="print" type="text/css">

I do not recommend leaving these two options as your only approach for a few reasons:

  • Altering the DOM for printing may be fine for basic pages, but the solution is not scalable. If your page has a layout beyond just a few simple elements, your print.css file can quickly grow in both size and complexity.
  • Site content typically has to stay in the same general area for printing. You can use something like Flexbox’s order and flex-direction properties to shift items around a bit, but we quickly run into limitations. 
  • You have to maintain your print styles in addition to your pages. If you add new elements to a page, your print styles will have to account for them as well.

We can look beyond the traditional approaches for now and move forward with creating this “blank canvas.” The first option that may come to mind for creating a blank canvas is to pop open a new window with window.open(). This approach may work, but we now have to consider pop-up blockers, sizing and positioning the new window, and the need to destroy the window once the user is done. Let’s shoot for a more seamless user experience. If we can’t use a new window, then how about a good ole iframe? 

Create an object to house your functionality:

See the Pen NeroScript.io Pretty Print by D’ontreye Nero (@dnero) on CodePen.

I wrote this with vanilla JavaScript to avoid having to pull in any dependencies and avoided using template literals and arrow functions due to the lack of IE support. I’m also using string concatenation for simplicity. In your project, you should use Handlebars (or some other templating engine) and consider the browsers you’ll need to support.

Let’s break down all of the internal methods here.

  • NsPrettyPrintPage.print() — this function prints the current page you’re on by creating an empty/hidden iframe and executing the print command
  • NsPrettyPrintPage.generatePrintLayout() — dynamically gathers body and footer html to be injected into iframe
  • NsPrettyPrintPage.generateHeaderHtml() —imports CSS from the current DOM to be applied to the iframe header
  • NsPrettyPrintPage.generateGlobalCss() — adds global classes like margins, image dimensions, and table breaking, to be present on every page
  • NsPrettyPrintPage.generateFooterHtml() — adds a global footer to every page
  • NsPrettyPrintPage.prettyPrintCodeForSamplePageType() — NsPrettyPrintPage.{{YOUR FN NAME HERE}}() allows you to customize each page on your site for pretty printing by page type

Identify elements you want on your printed pages

This is where things take a 180 from the traditional “print.css” approach. Instead of starting with the current DOM and hiding or rearranging the parts we don’t want to show, let’s take the “blank canvas” and create new pretty print page from there. 

Let’s assume our hypothetical product management team discovers that our users only want to see the product image, title, price, and rating in easy-to-scan columns when using our print feature.

We need to divert our thinking from what is useful when a user is surfing online to what is useful for a user with a physical, printed copy of our information.

While constructing the new page, remember to keep the use cases in mind here. Why do users really need to print this page? What are they doing with the paper? Do they need space to write notes? The page as-is on the web is probably not very useful on paper. No buttons will work, nor will the background images do much more than waste ink. 

Here is a sample print preview of a search for “keyboard” on amazon.com that returned 16 results.

amazon.com's search result print preview.

A few notes from the print output above: 

  • Our users will need seven sheets of paper to print this view
  • The Add to Cart buttons have been hidden, but we still have several elements that are not beneficial to our print process, like filters, navigation, and blank space which we could be using to display more items
  • This is not very useful for users who want to easily scan and compare items

Diving into the html for this page, we see that the result list is an unordered list with the id #s-results-list-atf.

HTML source from amazon.com's search result list.

We need to extract content from each list item, so let’s try to find a selector that is unique, but not so individual. If we check the classes, you’ll notice that all of the li tags have the class s-result-item, the ads have a class of AdHolder, and there is a top-rated brands section with the class acs-private-brands-container-background. Using a CSS querySelector, we can extract all of the items that are not ads or miscellaneous with the selector: #s-results-list-atf li.s-result-item:not(.AdHolder):not(.acs-private-brands-container-background).

Adding this page to our print feature requires a new function, plus a reference to it in our generatePrintLayout() function. Since we’re going to be printing this content and not worrying about responsiveness as much as we typically would, let’s stick with a simple table.

amazonSearchResults: function() {
let html = ''; // reference to all result items that are not ads
let resultItems = document.querySelectorAll('#s-results-list-atf li.s-result-item:not(.AdHolder):not(.acs-private-brands-container-background)');

html += '<table>';

// iterate over result items
resultItems.forEach(function(item) {
html += '<tr>';

// product image
html += '<td>' + item.querySelector('.s-access-image').outerHTML + '</td>';

// product title
html += '<td style="max-width: 400px;">' + item.querySelector('.s-access-title').innerHTML + '</td>';

// product price
html += '<td>' + item.querySelector('.sx-price-currency').innerHTML;
html += item.querySelector('.sx-price-whole').innerHTML + '.';
html += item.querySelector('.sx-price-fractional').innerHTML + '</td>';

// product rating
html += '<td style="min-width: 150px;">' + item.querySelector('.a-spacing-mini .a-icon-alt').innerHTML + '</td>';

html += '</tr>';
});

html += '</table>';

return html;
}

We only needed to extract the useful items requested by our “product management team” which slims our new print output down to two pages!

Pretty print version of amazon.com's search result page

This is a simple example of how you can transform your custom print feature without bulky solutions that will add yet another dependency. If you’re already using jQuery or any other library, it will fit right in with this solution. Simply swap out document.querySelectorAll('.myClass') with $('.myClass') for example and carry on. To make life easier, your DOM elements may need “data-” attributes on important elements to make them more easily identifiable, but you can use any JavaScript/HTML you’d like to target and extract what you need. Also note the use of innerHTML when the contents of a tag are needed, but outerHTML if you want to keep the tags as well, like when targeting a header<h2>My site header</h2>. outerHTML will drop the tag into the pretty print page as is.

Drawbacks

This feature can be implemented as a (custom) “print” button on your site, but it will not cover printing through default browser methods like right click > print, File > Print, and Ctrl/Cmd + P. The window.onbeforeprint() method can apply changes before the print job begins, but there is no way to cancel or override the default browser print job.

Testing this out for yourself

If you want to try this function on a pre-existing page or even a live site, I recommend using a Chrome extension called User JavaScript and CSS. Another option is to simply paste the NsPrettyPrint into your browser’s console. This has been tested in modern versions of Chrome, Safari, Firefox, and Edge, with graceful degradation for IE 11+.


Wrapping up

Now that you have a useful pretty print approach, feel free to extend this set-up however you’d like to fit your site. It is fairly easy to get up and running in no time. This print feature is designed to provide an identical experience to the default browser functionality. Be sure to scope this functionality properly or integrate it with your pre-existing print button or command function. Leave a comment or shoot me an email with any questions or comments.

Happy printing!

The 0, 1, 10, 100 Rule


When engineering a solution for front-end search results, I follow a personal rule I call the 0, 1, 10, 100 rule. Regardless of whether you’re a new or seasoned developer, UX designer, or product manager, the 0, 1, 10, 100 rule will help you stay mindful of all the result page possibilities you’ll need to address even before you get started. From writing user stories and designing screens, to coding the UI and creating API endpoints, the 0, 1, 10, 100 rule can kick off your conversations around how to handle front-end search results in your app.

Most often related to front-end search results, this rule applies to lists, result sets, or any type of display where there can be a variable amount of items returned. It helps you explore process flow options and uncover how you want to consistently handle certain features across your app.


These four numbers represent the following cases: 

  • 0 – an empty result set
  • 1 – a single result 
  • 10 – a handful of results
  • 100 – more results than can fit on the screen at once

0 — an empty result set

The “0” is a reminder to address how your page should appear when there are no results. Unless you’re a true test-driven developer, this rule is an easy one to overlook on your first pass. The desire to quickly “see something on the screen” might cause you to skip this rule and have to double back later. The empty result set is also a great place to suggest next steps, provide instructions, market, make a joke, etc. 

The Atlassian team provides a great example with their empty Bitbucket repository graphics and instructions. They make links and commands easy to copy, give you steps to follow, as well as links to get more information.

By the way, check out https://www.humaaans.com for free illustrations that will make your “0” rule stand out.

1 — a single result

“1” result provides a unique opportunity. You have several options including: 

  • skipping the results listing and forwarding users to a detail page of the single result
  • show the single result with similar/related items in the same view to make it appear as if there are more results than there actually are
  • show the single result above alongside related items

With a single front-end search result you have more space to fill, so you could augment it with related info or just forego that step altogether. This next step could be a detail page, a video, a profile, or whatever the next step in your flow may be. Always remember to take a step back and analyze your page holistically. Question your assumptions and make decisions that add value to your users. For example, should you keep the sort and filter options on the page for a single result? Weigh the consistency of keeping the controls present at all times versus removing a control that doesn’t serve much purpose for the user.

Amazon single item result set.
Walmart single item result set.

If you don’t have anything to add to a single front-end search result listing, then you may have an opportunity to skip a step. This could be a good move as long as it doesn’t confuse your users. Typically, the ultimate goal of a search is to find a single, specific result so this one could lean in your favor.

10 — a handful of results

“10” results is most likely the case you code for by default. It represents the presence of a few items that may or may not fit in a single view. A decision has to be made here on how you want to display things  —  whether a list, grid, table, or a combination of these using a toggle feature. 

100 — more results than can fit on the screen at once

“100” results ushers in a new list of considerations to manage. Now that you’re tasked with presenting dozens (if not thousands) of front-end search results to your user, you have some important decisions to make.

  • Should I use pagination? 
  • Should the pagination be server-side or client-side? 
  • I read a cool article the other day about infinite scroll…should I try that? 
  • Do I need to make my search results more meaningful and avoid massive result sets in the first place? I mean, when was the last time I went to page three of a Google search?

…the list goes on. It’s fine if your front-end search result set exceeds a few hundred items, but at some point you have to honestly ask yourself how useful your search results really are. Filters come in handy to help narrow your search, so be sure to give your users something useful in that regard.

Final thoughts

Obviously there are many other factors to consider when creating front-end search result screens including sorting, filtering, call-to-action buttons, and more, but the 0, 1, 10, 100 rule provides four buckets to get you on your way to covering all your bases.

  • keep all the various form factors in mind — think mobile, tablet, and desktop — as the decisions you make for desktop may not be the same you want for other device types
  • gather as much data as you can on how users truly use your app and do what’s best for them while following the 0, 1, 10, 100 rule