Skip to content

STU-22: Add custom local domain support for WordPress sites - #994

Merged
youknowriad merged 40 commits into
trunkfrom
add/custom-domain-support
Mar 10, 2025
Merged

STU-22: Add custom local domain support for WordPress sites#994
youknowriad merged 40 commits into
trunkfrom
add/custom-domain-support

Conversation

@youknowriad

@youknowriad youknowriad commented Mar 2, 2025

Copy link
Copy Markdown
Contributor

Related issues

Summary …

  • Implemented custom domain support for WordPress sites using a proxy server
  • Added UI for setting custom domains when creating sites
  • Integrated with system hosts file for local domain resolution
  • The user chooses a custom domain on site creation (editing an existing site is harder because it would require updates to the WP database).

Implementation details

  • Created a proxy server that listens on port 80 and forwards requests to the appropriate local site. This means that if 80 is already used, custom domains won't work (there's no way around this)
  • Added domain management in hosts file to resolve custom domains to localhost
  • Updated site details to store and display custom domain information
  • Modified URL display in settings to show custom domain when enabled
  • Added validation for custom domain format

Test plan

  • Create a new site with custom domain enabled
  • Verify the domain is added to hosts file (requires admin permission)
  • Visit the site using the custom domain (without port)
  • Verify admin and frontend URLs work properly
  • Delete the site and verify domain is removed from hosts file

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

Important note This PR has been created for a huge part using AI. My main purpose with this PR was to learn both Studio's code base and learn AI while implementing a useful feature.

Screenshot 2025-03-02 at 2 20 18 PM
@youknowriad youknowriad self-assigned this Mar 2, 2025
@youknowriad
youknowriad force-pushed the add/custom-domain-support branch 2 times, most recently from 4f49875 to 57a013b Compare March 2, 2025 13:23
Comment thread src/lib/proxy-server.ts Outdated
try {
console.log( 'Attempting to start proxy server with elevated privileges' );

if ( currentPlatform === 'win32' ) {

@youknowriad youknowriad Mar 3, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently in Windows, we need to run the proxy with admin rights. The AI proposed using netsh to forward to a custom port. I need someone to help me test Windows.

Comment thread src/lib/proxy-server.ts Outdated
@youknowriad
youknowriad requested review from sejas and wojtekn March 3, 2025 08:56
Comment thread src/lib/hosts-file.ts
Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/site-server.ts
Comment thread src/index.ts Outdated
@fredrikekelund
fredrikekelund requested review from a team and removed request for fredrikekelund, katinthehatsite, nightnei, sejas and wojtekn March 3, 2025 11:47
Comment thread src/lib/hosts-file.ts
Comment thread src/components/site-form.tsx Outdated
Comment thread src/components/site-form.tsx Outdated
Comment thread src/components/site-form.tsx Outdated

@fredrikekelund fredrikekelund left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to work relatively well in my light testing, which is great 👍 Still, this is a big feature, and we will need to test it thoroughly before landing.

A couple of initial high-level thoughts:

  • There are several visual issues in the Add site modal right now. We should get some designer input from @matt-west or someone else on how to implement this.
  • Users should be able to edit the domain after a site is added. This is already a big PR, so we don't necessarily need to implement that here, but it should go into the same release as this feature.
Comment on lines +229 to +276
useCustomDomain,
setUseCustomDomain,
customDomain,
setCustomDomain,
customDomainError,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the fault of this PR, but we should really move this state inside SiteForm and pass it back to the parent in the onSubmit handler. Too much prop drilling now with no clear benefit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entirely agree, I noticed it too :)

Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/lib/proxy-server.ts
Comment thread src/lib/proxy-server.ts
Comment thread src/storage/user-data.ts Outdated
Comment thread src/lib/hosts-file.ts
Comment thread src/lib/hosts-file.ts Outdated
Comment on lines +73 to +75
if ( domainRegex.test( hostsContent ) ) {
return; // Domain already exists
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do we do when this happens..? Display some kind of error in the app?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, I was thinking of cases when the domain is pointing to a different IP. Edge case, perhaps, but it ties into other error handling questions like #994 (comment)

Comment thread src/ipc-handlers.ts Outdated

@wojtekn wojtekn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The basic happy path works fine on Mac. I left some comments related to small issues and different cases.

Comment thread src/components/site-form.tsx Outdated
Comment thread src/components/site-form.tsx Outdated
Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/components/site-form.tsx Outdated
@youknowriad
youknowriad force-pushed the add/custom-domain-support branch from 264b825 to 48a1f37 Compare March 7, 2025 11:44
@youknowriad

Copy link
Copy Markdown
Contributor Author

Could we send a different message to showErrorMessageBox depending on the exception type/message and keep the old one for all exceptions but the ones stemming from sudoExec..? See source.

I don't see any other way other than checking the string or introducing a format/classes for errors. The latter is better but I think it warrants its own PR instead.

@youknowriad

Copy link
Copy Markdown
Contributor Author

@wojtekn What is the domain you're using to test the transliterated domains? In my testing these are rejected during validation at the moment (which could be a good way to start)

@fredrikekelund

Copy link
Copy Markdown
Contributor

I don't see any other way other than checking the string or introducing a format/classes for errors. The latter is better but I think it warrants its own PR instead.

Gotcha. I agree with all of that. Let's look into it separately 👍

@wojtekn

wojtekn commented Mar 7, 2025

Copy link
Copy Markdown
Contributor

What is the domain you're using to test the transliterated domains? In my testing these are rejected during validation at the moment (which could be a good way to start)

It was Japanese with the "マイ WordPress サイト" site name auto-generated. I pulled changes, but I don't see an auto-generated domain for any language.

@youknowriad

Copy link
Copy Markdown
Contributor Author

The second one is that I see ECONNREFUSED exception logged to the console when I start sites with custom domain. It doesn't seem to affect Studio, though.

I'm not seeing that at the moment but my guess is that it happens maybe because the apps is trying to generate a "preview" while the site is not ready yet. (just a guess).

@youknowriad

Copy link
Copy Markdown
Contributor Author

Thanks both of you for your valuable reviews. I think I've addressed all the points. Let me know if we're missing something.

@wojtekn

wojtekn commented Mar 7, 2025

Copy link
Copy Markdown
Contributor

Works great now! Thanks for adding test for the domain generation.

I'm not seeing that at the moment but my guess is that it happens maybe because the apps is trying to generate a "preview" while the site is not ready yet. (just a guess).

I can't reproduce it now, too.

Comment thread src/hooks/use-add-site.ts Outdated

@fredrikekelund fredrikekelund left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, @youknowriad 👍 Thanks for addressing all those comments. Let's make sure we get a design review for this before landing, but the core functionality looks mostly solid to me now (I just need to understand the logic around internationalized domain names)

Comment thread src/components/content-tab-settings.tsx Outdated
Comment thread src/hooks/use-add-site.ts Outdated
Comment thread src/lib/proxy-server.ts Outdated
Comment thread src/lib/proxy-server.ts
Comment thread src/lib/proxy-server.ts
Comment thread src/lib/proxy-server.ts Outdated
Comment thread src/lib/hosts-file.ts
Comment thread src/lib/hosts-file.ts
@matt-west

Copy link
Copy Markdown
Contributor

Thanks @youknowriad. A lot of users are going to love this feature!

I tested this locally and it worked well, although starting the site after entering my system password was quite slow.

What’s stopping us from creating a custom domain for every new site that’s created in Studio? Local takes that approach. I feel like the custom domain field should be directly under Site name. That would also allow us to eliminate the checkbox.


A few things I noticed testing this.

  1. The Advanced settings dropdown and Local path field are misaligned.
Screenshot 2025-03-07 at 17 05 55
  1. Let’s display the password note on the Domain name field instead and update the copy to:

Your system password will be required to set up the domain.

  1. There’s no way to edit the domain after I’ve created the site. Perhaps that’s coming in a follow-up PR?

  2. Was the custom domain option added to the onboarding screen too? (I don’t have an easy way to test that.)

@youknowriad

Copy link
Copy Markdown
Contributor Author

What’s stopping us from creating a custom domain for every new site that’s created in Studio? Local takes that approach. I feel like the custom domain field should be directly under Site name. That would also allow us to eliminate the checkbox.

Local has a "router mode" that is applied globally that you can disable. Also switching it back and forth means all your existing sites would stop working for now. Personally I prefer the control site per site but we can always have it as a global mode later. The reason we don't do it automatically though is that it depends on admin rights and not all the users have these.

The Advanced settings dropdown and Local path field are misaligned.

This was a result of a rebase, it's now fixed

Let’s display the password note on the Domain name field instead and update the copy to:

This is addressed too

There’s no way to edit the domain after I’ve created the site. Perhaps that’s coming in a follow-up PR?

A potential follow-up indeed, but it's not that simple because it requires updating the WP database for existing sites.

Was the custom domain option added to the onboarding screen too? (I don’t have an easy way to test that.)

Yes

@fredrikekelund

Copy link
Copy Markdown
Contributor

The Advanced settings dropdown and Local path field are misaligned.

That looks like a regression unrelated to this PR. I've created https://github.com/Automattic/dotcom-forge/issues/10582 to track it. It still looks better with @youknowriad's latest changes – at least the local path and domain fields are consistently aligned now.

@youknowriad

Copy link
Copy Markdown
Contributor Author

Can I get an approval here? What do you think is left?

@fredrikekelund fredrikekelund left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran another round of tests on Mac and Windows – it's looking good and works as expected. I did however encounter one more error handling scenario that I think we should handle before landing this PR (EADDRINUSE errors on port 80).

I believe we should be good to land this PR after addressing that 👍

Comment thread src/lib/hosts-file.ts Outdated
Comment thread src/lib/proxy-server.ts
Comment thread src/lib/proxy-server.ts
Comment thread src/lib/proxy-server.ts Outdated
Comment thread src/index.ts Outdated

@fredrikekelund fredrikekelund left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, @youknowriad! We should be good to land this now 👍

Let's add some additional rows to our smoke testing sheet for this feature, @wojtekn. That gives us another chance to catch potential errors before the next release.

@youknowriad
youknowriad merged commit e5cc16d into trunk Mar 10, 2025
@youknowriad
youknowriad deleted the add/custom-domain-support branch March 10, 2025 10:09
@wojtekn

wojtekn commented Mar 10, 2025

Copy link
Copy Markdown
Contributor

Let's add some additional rows to our smoke testing sheet for this feature, @wojtekn. That gives us another chance to catch potential errors before the next release.

I've added a test case for local domain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

9 participants