What is the proper way to set `currentSite` in a CP template when managing multi-site stuff in Craft 3?
Maybe this is some kind of broad answer too but when you take a look at your CP requests you'll see: the siteHandle is mostly passed as a variable in nearly every request.

As for the URL routes the last segment is always the siteHandle: By default, the current site will be used in every query but as soon as Craft recognizes a bodyParam siteId/criteria['siteId'] (for example in your baseElementIndex) or in the URL route it uses that site for all ElementQueries.

In your CP there is no such a thing like currentSite (at least it is not really used for important logic) instead the current site is determined like 

{% for siteId in groupSiteIds %}
    {% if siteId == entry.siteId %} 
        // currentSite = entry.siteId
    {% else %}
        // not the current site
    {% endif %}
{% endif %}


When I started I used the same method to check for a parameter siteId within the bodyParam criteria. My plugin routes are always something like this

$event-&gt;rules[] = [
    'pattern' =&gt; 'form-builder/elements/&lt;action:&gt;/&lt;id:\d+&gt;/&lt;siteHandle:\w+&gt;',
    'route' =&gt; 'form-builder/element/&lt;action&gt;',
    'defaults' =&gt; [
        'id' =&gt; null,
        'siteHandle' =&gt; Craft::$app-&gt;getSites()-&gt;getPrimarySite()-&gt;handle,
        'action'    =&gt; 'index'
    ]
];


if no siteHandle is passed I use the Craft::$app-&gt;getSites()-&gt;getPrimarySite()

craft\controllers\EntriesController

public function actionEditEntry(string $sectionHandle, int $entryId = null, int $draftId = null, int $versionId = null, string $siteHandle = null, Entry $entry = null): Response
if ($siteHandle !== null) {
    $variables['site'] = Craft::$app-&gt;getSites()-&gt;getSiteByHandle($siteHandle);

    if (!$variables['site']) {
        throw new NotFoundHttpException('Invalid site handle: '.$siteHandle);
    }
}


later on, when there is really nothing at all it just assumes the following

if (empty($variables['site'])) {
    /** @noinspection PhpUnhandledExceptionInspection */
    $variables['site'] = Craft::$app-&gt;getSites()-&gt;getCurrentSite();

    if (!in_array($variables['site']-&gt;id, $variables['siteIds'], false)) {
        $variables['site'] = Craft::$app-&gt;getSites()-&gt;getSiteById($variables['siteIds'][0]);
    }

    $site = $variables['site'];
}


TL:DR

Craft doesn't use the currentSite that much in the CP, it is determined by the current element.siteId or the siteMenu (in js). As soon as you enter the CP the selected site in the menu will be stored in your Javascript session, when you click on create new entry you'll get routed to the site that is specified in your session. I think it's best to manage it the same way